- 原文地址:High Performance React: 3 New Tools to Speed Up Your Apps
- 原文做者:Ben Edelstein
- 译文出自:掘金翻译计划
- 本文永久连接:github.com/xitu/gold-m…
- 译者:sunui
- 校对者:yzgyyang、reid3290
一般来讲 React 是至关快的,但开发者也很容易犯一些错误致使出现性能问题。组件挂载过慢、组件树过深和一些非必要的渲染周期能够迅速地联手拉低你的应用速度。前端
幸运的是有大量的工具,甚至有些是 React 内置的,能够帮助咱们检测性能问题。本文将着重介绍一些加快 React 应用的工具和技术。每一部分都配有一个可交互并且(但愿是)有趣的 demo!react
React 15.4.0 引入了一个新的性能时间轴特性,能够精确展现组件什么时候挂载、更新和卸载。也可让你可视化地观察组件生命周期相互之间的关系。android
注意: 目前,这一特性仅支持 Chrome、Edge 和 IE,由于它调用的 User Timing API 尚未在全部浏览器中实现。ios
react_perf
。例如, http://localhost:3000?react_perf
每个色条显示的是一个组件作“处理”的时间。因为 JavaScript 是单线程的,每当一个组件正在挂载或渲染,它都会霸占主线程,并阻塞其余代码运行。git
像 [update]
这样中括号内的文字描述的是生命周期的哪个阶段正在发生。把时间轴按照步骤分解,你能够看到依据方法的细粒度的计时,好比 [componentDidMount]
[componentWillReceiveProps]
[ctor]
(constructor) 和 [render]
。github
堆叠的色条表明组件树,虽然在 React 拥有过深的组件树也比较典型,但若是你想优化一个频繁挂载的组件,减小嵌套组件的数量也是有帮助的,由于每一层都会增长少许的性能和内存消耗。web
这里须要注意的是时间轴中的计时时长是针对 React 的开发环境构建的,会比生产环境慢不少。实际上性能时间轴自己也会拖慢你的应用。虽然这些时长不能表明真正的性能指标,但不一样组件间的相对时间是精确的。并且一个组件是否彻底被更新不取决因而否是生产环境的构建。npm
出于乐趣,我故意写了一个具备严重性能问题的 TodoMVC 应用。你能够在这里尝试。后端
打开 Chrome 开发者工具,切换到 “Performance” 栏,点击 Record 开始记录时间轴。而后在应用中添加一些 TODO,中止记录,检查时间轴。看看你能不能找出形成性能问题的组件 :)浏览器
在 React 中最影响性能的问题之一就是非必要的渲染周期。默认状况下,一旦父组件渲染,React 组件就会跟着从新渲染,即便它们的 props 没有变化也是如此。
举个例子,若是我有一个简单的组件长这样:
class DumbComponent extends Component {
render() {
return <div> {this.props.value} </div>;
}
}复制代码
它的父组件是这样:
class Parent extends Component {
render() {
return <div>
<DumbComponent value={3} />
</div>;
}
}复制代码
每当父组件渲染,DumbComponent
就会从新渲染,尽管它的 props 没有改变。
通常来说,若是 render
运行,而且虚拟 DOM 没有改变,并且既然 render
应该是个纯净的没有任何反作用的方法,那么这就是一个没必要要的渲染周期。在一个大型应用中检测这种事情是很是困难的,但幸运的是有一个工具能够帮得上忙。
why-did-you-update
是一个 React 钩子工具,用来检测潜在的非必要组件渲染。它会检测到被调用但 props 没有改变的组件 render
。
npm i --save-dev why-did-you-update
在你应用中的任何地方添加下面这个片断:
import React from 'react'
if (process.env.NODE_ENV !== 'production') {
const {whyDidYouUpdate} = require('why-did-you-update')
whyDidYouUpdate(React)
}
注意: 这个工具在本地开发环境使用起来很是棒,可是要确保生产环境要禁用掉,由于它会拖慢你的应用。
why-did-you-update
在运行时监听你的应用,并用日志输出可能存在非必要更新的组件。它让你看到一个渲染周期先后的 props 对比,来决定是否可能存在非必要的更新。
为了演示 why-did-you-update
,我在 TodoMVC 中安装了这个库并放在 Code Sandbox 网站上,这是一个在线的 React 练习场。 打开浏览器控制台,并添加一些 TODO 来查看输出。
注意这个应用中不多的组件存在非必要渲染。尝试执行上述的技术来避免非必要渲染,若是操做正确,why-did-you-update
不会在控制台输出任何内容。
React Developer Tools 这个 Chrome 扩展有一个内置特性用来可视化组件更新。这有助于防止非必要的渲染周期。使用它,首先要确保在这里安装了这个扩展。
而后点击 Chrome 开发者工具中的 “React” 选项卡打开扩展并勾选“Highlight Updates”。
而后简单操做你的应用。和不一样的组件交互并观察 DevTools 施展它的魔法。
React Developer Tools 在给定的时间点高亮正在从新渲染的组件。根据更新的频率,使用不一样的颜色。蓝色显示罕见更新,通过绿色、黄色的过渡,一直到红色用来显示更新频繁的组件。
看到黄色或红色并不必要以为必定是坏事。它可能发生在调整一个滑块或频繁触发更新的其余 UI 元素,这属于意料之中。但若是当你点击一个简单的按钮而且看到了红色这可能就意味着事情不对了。这个工具的目的就是识破正在发生非必要更新的组件。做为应用的开发者,你应该对给定时间内哪一个组件应该被更新有一个大致的概念。
为了演示高亮,我故意让 TodoMVC 应用更新一些非必要的组件。
打开上面的连接,而后打开 React Developer Tools 并启用更新高亮。当你在上面的文字输入框中输入内容时,你将看到全部的 TODO 非必要地高亮。你输入得越快,你会看到颜色变化指示更新愈来愈频繁。
一旦你已经肯定应用中非必要从新渲染的组件,有几种简单的方法来修复。
在上面的例子中,DumbComponent
是只接收属性的纯函数。这样,组件就只有当它的 props 变化的时候才从新渲染。React 有一个特殊的内置组件类型叫作 PureComponent
,就是适用这种状况的用例。
与继承自 React.Component 相反,像这样使用 React.PureComponent:
class DumbComponent extends PureComponent {
render() {
return <div> {this.props.value} </div>;
}
}复制代码
那么只有当这个组件的 props 实际发生变化时它才会被从新渲染了。就是这样!
注意 PureComponent
对 props 作了一个浅对比,所以若是你使用复杂的数据结构,它可能会错失一些属性变化而不会更新你的组件。
shouldComponentUpdate
是一个在 render
以前 props
或 state
发生改变时被调用的组件方法。若是 shouldComponentUpdate
返回 true,render
将会被调用,若是返回 false 什么也不会发生。
经过执行这个方法,你能够命令 React 在 props 没有发生改变的时候避免给定组件的从新渲染。
例如,咱们能够在上文中的 DumbComponent 中这样调用 shouldComponentUpdate
。
class DumbComponent extends Component {
shouldComponentUpdate(nextProps) {
if (this.props.value !== nextProps.value) {
return true;
} else {
return false;
}
}
render() {
return <div>foo</div>;
}
}复制代码
React Developer Tools 只能在你本身的机器上运行的应用中使用。若是您有兴趣了解用户在生产中看到的性能问题,试试 LogRocket。
LogRocket 就像是 web 应用的 DVR,会记录发生在你的站点上的全部的一切。你能够重现带有 bug 或性能问题的会话来快速了解问题的根源,而不用猜想问题发生的缘由。
LogRocket 工具为你的应用记录性能数据、Redux actions/state、日志、带有请求头和请求体的网络请求和响应以及浏览器的元数据。它也能记录页面上的 HTML 和 CSS,甚至能够为最复杂的单页面应用从新建立完美像素的视频。
LogRocket | 为 JavaScript 应用而生的日志记录和会话回放工具
LogRocket 帮助你了解用影响你用户的问题,这样你就能够回过头来构建伟大的软件了。
logrocket.com
感谢阅读,但愿这些工具和技术能在你的下一个 React 项目中帮到你!
掘金翻译计划 是一个翻译优质互联网技术文章的社区,文章来源为 掘金 上的英文分享文章。内容覆盖 Android、iOS、React、前端、后端、产品、设计 等领域,想要查看更多优质译文请持续关注 掘金翻译计划。