【问题标题】:React.memo performance is worse than with React.PureComponentReact.memo 的性能比 React.PureComponent 差
【发布时间】:2018-10-26 13:31:21
【问题描述】:

前段时间我对单元格渲染器组件进行了重构以实现性能提升(我有一个巨大的表)。我确实从功能性无状态组件重构为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.0 和react-dom@16.6.0(从16.5.2)并从PureComponent 重构为React.memo,期望它会更快(不生命周期方法被调用,函数小于内存中的类等......):

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;

令我惊讶的是,性能显着下降。

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

prod 模式下的配置文件数据(chrome 中没有插件)显示,与之前使用 PureComponent 相比,发生了更多的脚本编写(我的案例的脚本编写时间从 0.5 秒变为 3.8 秒)。

编辑:经过一番调查,这似乎不是 React.memo 的问题,而是新版本的 React。我已将单元格渲染器恢复为 PureComponent 并保留了新的 react@16.6.0 版本,结果(性能显着降低)仍然存在

【问题讨论】:

  • 你能把它作为一个问题报告到他们的 github 上吗?

标签: reactjs


【解决方案1】:

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

问题总结(2018-11-11):

  • 该问题与 React 本身无关,而是与 uglify-es(错误)优化有关。
  • uglify-es 是内联代码(不应内联)。
  • uglify-es 不再积极维护。
  • 建议的解决方案是使用terser 作为替代。
  • 如果您使用uglifyjs-webpack-plugin 或Webpack 4.x.x(默认使用uglifyjs-webpack-plugin),您应该像这样更改webpack configuration 中的缩小器选项:

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

【讨论】:

    【解决方案2】:

    TL;DR:

    将 webpack 升级到 4.26 版

    因为他们切换到terser 作为默认最小化程序。

    背景:

    • uglifyjs-webpack-plugin uglify-js
    • 但是 uglify-js 不支持 ES6,这导致了一个名为 uglify-es 的分支,它是在 uglify-js 存储库中开发的,但在 harmony 分支下
    • uglifyjs-webpack-plugin v1.x 切换到 uglify-es 以获得 ES6 支持
    • 然而uglify-es 停止维护:mishoo/UglifyJS2#3156(评论)
    • 这导致了一个名为 terser 的分支,它包含了所有未合并的 PR,并将成为所有新开发发生的地方:https://github.com/fabiosantoscode/terser
    • terser-webpack-plugin 已创建,这是 terser 等效于 uglifyjs-webpack-plugin: https://github.com/webpack-contrib/terser-webpack-plugin
    • uglifyjs-webpack-plugin v2.x 将切换回 uglify-js,因此任何需要支持 ES6 的项目现在都需要切换到 terser-webpack-plugin。

    参考:webpack/commit

    【讨论】:

      猜你喜欢
      • 2021-10-30
      • 2022-10-03
      • 1970-01-01
      • 1970-01-01
      • 2021-03-04
      • 2020-01-10
      • 1970-01-01
      • 1970-01-01
      • 2020-11-02
      相关资源
      最近更新 更多