深入浅出React.js 性能分析


深入浅出React.js 性能分析

文章插图
 
 
作者 | Addy Osmani
译者 | 许学文
策划 | 蔡芳芳
转发链接:https://mp.weixin.qq.com/s/ciIl4Cg9ZULDUY77Yuot0A
本文最初发布于Addy Osmani博客,经原作者授权由 InfoQ 中文站翻译并分享
今天我将向大家演示如何使用 React Profiler API、Tracing API 以及 User Timing API 来分别追踪 React 的组件渲染、用户交互以及自定义性能指标 。
React Profiler API
首先来了解下 React Profiler,它主要用来追踪应用组件的 渲染过程 以及渲染开销,同时标记出应用的性能瓶颈 。Profiler 接受一个 onRender 回调函数,当被追踪的组件以及子代组件发生更新时,该函数就会被调用 。下图是在影片排期应用中使用 Profiler 追踪各个组件渲染:
深入浅出React.js 性能分析

文章插图
 
Profiler 中 onRender 回调函数的具体参数如下:
  • id:: 这是 Profiler 的唯一标示,区分是哪个 Profiler 追踪的组件树发生了更新
  • phase: 如果更新是挂载阶段这个值就是“mount”,如果是二次渲染阶段就是“update”
  • act ualDuration: 更新花费的渲染时间
  • baseDuration: 更新预计花费的渲染时间
  • startTime: 更新开始时间点
  • commitTime: 更新提交的时间点
  • interactions: 更新中包含的交互信息
 
const callback = (id, phase, actualTime, baseTime, startTime, commitTime) => {    console.log(`${id}'s ${phase} phase:`);    console.log(`Actual time: ${actualTime}`);    console.log(`Base time: ${baseTime}`);    console.log(`Start time: ${startTime}`);    console.log(`Commit time: ${commitTime}`);}运行上面的代码,在 Chrome 调试器中可以看到如下输出:
深入浅出React.js 性能分析

文章插图
 
也可以打开 React DevTools,在 Profiler 面板中可以看到组件渲染的时间火焰图:
深入浅出React.js 性能分析

文章插图
 
切换到排序视图
深入浅出React.js 性能分析

文章插图
 
当然也可以使用多个 Profiler 来分别追踪应用中的各个不同的部分,示例代码如下:
import React, { Fragment, unstable_Profiler as Profiler} from "react";render(  <App>    <Profiler id="Header" onRender={callback}>      <Header {...props} />    </Profiler>    <Profiler id="Movies" onRender={callback}>      <Movies {...props} />    </Profiler>  </App>)知道了如何追踪组件渲染,那么如果想跟踪交互,该怎么做?
交互追踪 Tracing API
想一下,如果能追踪到交互(例如:按钮的点击),那么在回答“这个按钮点击花费了多少时间更新 DOM?”这样的问题时是不是就有了依据 。要感谢 Brian Vaughn 的努力,React 在其 调度包 中引入了对这个功能的试验支持,更详细的说明可以点击 这里 查看 。
一个交互追踪,需要包含一个描述(例如:添加购物车按钮被点击)、一个时间戳和一个回调函数,在回调函数中你可以定义一些和该交互相关的逻辑 。在“影片排期应用”中就有一个添加电影到播放列表的“+”号按钮,这个就是一个交互按钮 。
深入浅出React.js 性能分析

文章插图
 
下面的代码演示了如何追踪这个按钮的点击行为:
import { unstable_Profiler as Profiler } from "react";import { render } from "react-dom";import { unstable_trace as trace } from "scheduler/tracing";class MyComponent extends Component {  addMovieButtonClick = event => {    trace("Add To Movies Queue click", performance.now(), () => {      this.setState({ itemAddedToQueue: true });    });  };在 React 开发调试工具的 interaction 面板中可以看到具体的交互行为和持续时间:


推荐阅读