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
。这通常可以为你提供很好的性能提升。