React.memo性能比React.PureComponent差

时间:2018-10-26 13:31:22

标签: reactjs

前一段时间,我确实重构了单元渲染器组件以实现性能提升(我有一张大桌子)。我确实将功能性无状态组件重构为PureComponent。例如:

import React from 'react';
import PropTypes from 'prop-types';

class SomeCell extends React.PureComponent {
  render() {
    const { pizzaOrder } = this.props;
    return (
      <>
        {pizzaOrder.name}
        <br />
        {pizzaOrder.price}
      </>
    );
  }
}

SomeCell .propTypes = {
  pizzaOrder: PropTypes.object,
};

export default SomeCell ;

现在我看到React.memo已发布,因此我更新为react@16.6.0react-dom@16.6.0(从16.5.2)并从PureComponent重构为{{1} },希望它会更快(没有生命周期方法被调用,功能小于内存中的类等):

React.memo

令我惊讶的是,性能大幅下降。

您知道这可能是什么问题吗?

prod模式下的配置文件数据(Chrome中没有插件)显示,import React from 'react'; import PropTypes from 'prop-types'; const SomeCell = React.memo(function({ pizzaOrder }) { return ( <> {pizzaOrder.name} <br /> {pizzaOrder.price} </> ); }); SomeCell .propTypes = { pizzaOrder: PropTypes.object, }; export default SomeCell; 脚本的发生要比以前多(我的案例的脚本时间从0.5s缩短到3.8sek)。

编辑:经过一些调查,似乎这与React.memo无关,但与新版本的React无关。我已将单元格渲染器还原为PureComponent并保留了新的react@16.6.0版本,结果(性能显着降低)仍然存在

2 个答案:

答案 0 :(得分:5)

如@skyboyer所建议,在React Repository中创建了一个问题。

问题摘要(2018-11-11):

  • 该问题与React本身无关,而与uglify-es(越野车)优化有关。
  • uglify-es是内联代码(不应内联)。
  • uglify-es不再处于主动维护状态。
  • 建议的解决方案是使用terser代替。
  • 如果您使用的是uglifyjs-webpack-plugin或Webpack 4.xx(默认情况下使用uglifyjs-webpack-plugin),则应像这样更改webpack configuration中的minifier选项:

    const TerserWebpackPlugin = require('terser-webpack-plugin');
    
    module.exports = {
      //...
      optimization: {
        minimizer: [
          new TerserWebpackPlugin({ /* your config */ })
        ]
      }
    };
    

答案 1 :(得分:5)

TL; DR:

  

将webpack升级到4.26版

,因为他们切换为terser作为默认的最小化工具。

背景

  • uglifyjs-webpack-plugin uglify-js
  • 但是uglify-js不支持ES6,这导致在uglify-es存储库中但在uglify-js分支下开发了名为harmony的fork
  • uglifyjs-webpack-plugin v1.x已切换为uglify-es以支持ES6
  • 然而uglify-es停止维护:mishoo / UglifyJS2#3156(评论)
  • 这导致了一个名为terser的分支,该分支合并了所有未合并的PR,并将在其中进行所有新开发:https://github.com/fabiosantoscode/terser
  • terser-webpack-plugin已创建,相当于terser的{​​{1}}:https://github.com/webpack-contrib/terser-webpack-plugin
  • uglifyjs-webpack-plugin v2.x将切换回uglifyjs-webpack-plugin,因此现在任何需要支持ES6的项目都需要切换至uglify-js

参考: webpack/commit