Optimizing Performance

优化性能

在内部,React 使用几种聪明的技术来最小化更新 UI 所需的昂贵 DOM 操作的数量。对于许多应用程序而言,使用 React 将导致快速的用户界面,而无需专门针对性能进行优化。不过,有几种方法可以加速您的 React 应用程序。

使用生产构建

如果您在 React 应用程序中进行基准测试或遇到性能问题,请确保您正在使用缩小的生产版本进行测试。

默认情况下,React 包含许多有用的警告。这些警告在开发中非常有用。但是,他们会使React变得越来越大,所以您应该确保在部署应用程序时使用生产版本。

如果您不确定您的构建过程是否设置正确,可以通过安装适用于 Chrome 的 React Developer Tools 进行检查。如果您在生产模式下使用 React 访问网站,该图标将具有黑色背景:

如果您以开发模式访问 React 网站,该图标将具有红色背景:

预计在使用应用程序时使用开发模式,在将应用程序部署到用户时使用生产模式。

您可以在下面找到有关为您的应用生成应用的说明。

创建 React App

如果您的项目是使用 Create React App 构建的,请运行:

npm run build

这将在build/您的项目文件夹中创建您的应用程序的生产版本。

请记住,这只是在部署到生产之前需要的。对于正常的开发,使用npm start

单文件构建

我们提供 React 和 React DOM 的生产就绪版本作为单个文件:

<script src="https://unpkg.com/react@16/umd/react.production.min.js"></script> <script src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>

请记住,只有以结尾的 React 文件.production.min.js适用于生产。

分支

为了最有效的 Brunch 生产版本,安装uglify-js-brunch插件:

# If you use npm npm install --save-dev uglify-js-brunch # If you use Yarn yarn add --dev uglify-js-brunch

然后,要创建生产版本,请将-p标志添加到build命令中:

brunch build -p

请记住,您只需要为生产构建执行此操作。你不应该-p在开发中通过标志或应用这个插件,因为它会隐藏有用的 React 警告,并且使构建慢得多。

Browserify

对于最高效的 Browserify 生产版本,安装一些插件:

# If you use npm npm install --save-dev envify uglify-js uglifyify # If you use Yarn yarn add --dev envify uglify-js uglifyify

要创建生产版本,请确保您添加这些转换(顺序很重要)

  • envify变换确保正确的编译环境设置。使其成为全球(-g)。

  • uglifyify转换消除了开发导入。使它成为全局(-g)。

  • 最后,产生的束被传送到束缚uglify-js(阅读为什么)

例如:

browserify ./index.js \ -g [ envify --NODE_ENV production ] \ -g uglifyify \ | uglifyjs --compress --mangle > ./bundle.js

注意: 包名称是uglify-js,但它提供的二进制文件被调用uglifyjs。这不是一个错字。

请记住,您只需要为生产构建执行此操作。你不应该在开发中应用这些插件,因为它们会隐藏有用的 React 警告,并使构建更慢。

卷起

要获得最高效的汇总生产版本,请安装一些插件:

# If you use npm npm install --save-dev rollup-plugin-commonjs rollup-plugin-replace rollup-plugin-uglify # If you use Yarn yarn add --dev rollup-plugin-commonjs rollup-plugin-replace rollup-plugin-uglify

要创建生产版本,请确保您添加这些插件(该订单很重要)

  • replace插件确保设置正确的构建环境。

  • commonjs插件提供对 Rollup 中 CommonJS 的支持。

  • uglify插件压缩和轧液最终束。

plugins: [ // ... require('rollup-plugin-replace'){ 'process.env.NODE_ENV': JSON.stringify('production') }), require('rollup-plugin-commonjs')(), require('rollup-plugin-uglify')(), // ... ]

有关完整的设置示例,请参阅此要点

请记住,您只需要为生产构建执行此操作。您不应该在开发中将uglify插件或replace插件应用于'production'值,因为它们会隐藏有用的 React 警告,并且使构建更慢。

WebPack

注意: 如果您使用 Create React App,请按照上述说明操作。本节仅与直接配置 webpack 有关。

要获得最高效的 webpack 生产版本,请确保将这些插件包含在您的生产配置中:

new webpack.DefinePlugin{ 'process.env.NODE_ENV': JSON.stringify('production') }), new webpack.optimize.UglifyJsPlugin()

你可以在 webpack 文档中了解更多。

请记住,您只需要为生产构建执行此操作。你不应该在开发中应用UglifyJsPlugin或者DefinePlugin具有'production'价值,因为它们会隐藏有用的React警告,并且使构建变得更慢。

使用 Chrome 性能标签分析组件

开发模式中,您可以使用受支持的浏览器中的性能工具来可视化组件的安装,更新和卸载方式。例如:

在 Chrome 中执行此操作:

  • 在查询字符串中?react_perf加载您的应用程序(例如,http://localhost:3000/?react_perf)。

  • 打开 Chrome DevTools 性能选项卡并按下记录

  • 执行你想要分析的动作。记录时间不要超过20秒,否则 Chrome 可能会挂起。

  • 停止录制。

5. 反应事件将被分组在User Timing标签下。

  • Immutable:一旦创建,一个集合不能在另一个时间点被修改。

  • Persistent:可以根据以前的集合和诸如集合之类的变体创建新集合。新集合创建后,原始集合仍然有效。

  • Structural Sharing:使用与原始集合尽可能多的相同结构创建新集合,尽量减少复制以提高性能。

不变性使追踪变化便宜。更改总是会导致一个新的对象,所以我们只需要检查对象的引用是否已经改变。例如,在这个常规的 JavaScript 代码中:

const x = { foo: 'bar' }; const y = x; y.foo = 'baz'; x === y; // true

虽然y是编辑过的,但由于它是对同一个对象的引用,所以x此比较返回true。你可以用 immutable.js 编写类似的代码:

const SomeRecord = Immutable.Record{ foo: null } const x = new SomeRecord{ foo: 'bar' } const y = x.set('foo', 'baz' const z = x.set('foo', 'bar' x === y; // false x === z; // true

在这种情况下,由于在变异时返回一个新的引用x,所以我们可以使用引用相等性检查(x === y)来验证存储的新值与存储在y其中的原始值不同x

另外两个可以帮助使用不可变数据的库是无缝不可变和不可变的帮助器

不可变的数据结构为您提供了一种便捷的方式来跟踪对象的变化,这是我们需要实现的shouldComponentUpdate。这通常可以为你提供很好的性能提升。