React服务器端渲染内存泄漏

时间:2019-03-22 07:19:21

标签: reactjs serverside-rendering react-server

以下根据链接react的代码表示:

  

不幸的是,这可能会导致服务器渲染的内存泄漏(其中   componentWillUnmount将永远不会被调用)

// Before
class ExampleComponent extends React.Component {
  componentWillMount() {
    this.setState({
      subscribedValue: this.props.dataSource.value,
    });

    // This is not safe; it can leak!
    this.props.dataSource.subscribe(
      this.handleSubscriptionChange
    );
  }

  componentWillUnmount() {
    this.props.dataSource.unsubscribe(
      this.handleSubscriptionChange
    );
  }

  handleSubscriptionChange = dataSource => {
    this.setState({
      subscribedValue: dataSource.value,
    });
  };
}

我不明白这怎么可能是服务器端的内存泄漏。例如,假设我们有这段代码在服务器端呈现,而ExampleComponent包含内存泄漏。

import React from 'react';
import ReactDomServer from 'react-dom/server';
import App from './components/index'

const serverRender =  () =>{
    return ReactDomServer.renderToString(<ExampleComponent />);
};

export default serverRender;

当这返回到客户端时,呈现的组件未附加到任何地方,并准备好进行GB收集。那为什么会有内存泄漏呢?

2 个答案:

答案 0 :(得分:0)

this.props.dataSource是外部事物,可以比调用subscribe的组件生存更长的时间。 handleSubscriptionChange将引用this.props.dataSource。同样,组件this中的handleSubscriptionChange可能会引用该组件本身。因此,GB根本不会清理ExampleComponent

componentWillMount被弃用以来,您可能不必担心这些详细信息,而只需使用componentDidMaount

答案 1 :(得分:0)

答案提示在文档中:

  

人们经常认为componentWillMountcomponentWillUnmount总是配对,但这并不能保证

一个明显的原因是componentWillMount在组件要即将安装时运行,因此,如果安装中断,则该组件将永远不会挂载,因此也永远不会挂载。但是,在文档的上一部分中也有暗示的原因,其中显示了代码:

componentWillMount() {

    this.setState({
      subscribedValue: this.props.dataSource.value,
    });

    // This is not safe; it can leak!
    this.props.dataSource.subscribe(
      this.handleSubscriptionChange
    );

} 

  

上面的代码对于服务器渲染(将不使用外部数据)和即将到来的异步渲染模式(其中请求可能多次发起)都是有问题的。

由此可以假设componentWillMount确实在SSR期间运行,并且还可以在客户端加水时运行,这意味着有一个额外的不必要请求正在引起服务器上潜在的内存泄漏。

但是,如果您使用componentDidMount,则可以保证:

  1. 仅在客户端运行
  2. 确保componentWillUnmount之后将始终运行