Profiler
React16.5 正式在 devtool 中加入了 Profiler 功能, 用于收集每次变更导致的渲染时间, 帮助开发者发现潜在的性能问题, 有助于开发更高性能的 React 应用
官方博客
如何使用
在 Chrome 的开发工具插件 react devtool 中多了一个 Profiler 的 tab, 点击可以切换到 Profiler 界面
在你使用 React16.5 之后的版本中, 开发时默认开启 Profiler 功能, 要想在正是环境也使用这个功能, 可以看这里
默认打开 Profiler 什么都没有, 要点击录制按钮进行记录 (跟 Chrome 的 performance 挺像).
在你开始录制之后你可以进行一些你想分析的操作, 然后再点击 stop 来停止录制, 就可以得到录制的内容
录制内容分析
首先要了解一点, React 在 16 版本之后处理任务分为两个阶段:
render 阶段判断哪些变更需要被处理成 DOM, 也就是比较上一次渲染的结果和新的更新
commit 阶段 React 最终达成所有变更 (也就是从 JS 对象到 DOM 的更新), 并且会调用 componentDidMount 和 componentDidUpdate 这些生命周期方法
开发工具中通过 commit 阶段对性能数据进行编组, 会显示在右侧工具栏上
看上去像一个柱状图, 每一个柱子代表一次 commit, 他的颜色和高度对应执行时长, 越高颜色越黄代表时间越长, 反之越短.
删选 commits
可以通过 commits 分组左边的设置图标点击出现的对话框设置删选选项, 可以设置:
执行时间少于多少的不展示
是否显示原声 DOM 渲染的时间
火焰图
火焰图部分会以一个类似树形的结构显示一次 commit 过程中整个每个组件的渲染信息, 跟 commit 分组信息类似, 颜色和长短对应这个组件的渲染耗时, 当然组件的渲染时间需要依赖他的子组件的渲染时间.
上图中可见 Router 组件渲染时间最长, 也基本等于 Nav 和 Route 的渲染时间之和, 因为子组件的渲染最终肯定会被计算在父组件的渲染时间内.
你可以点击任何一个组件来查看他的详细信息
点击一个组件还可以查看他的 props 和 state
有些时候你选中一个组件, 在 commits 分组中进行切换, 在 state 和 props 面板会有内容变化的提示
排名视图
选中火焰图边上的排名视图, 会展示该次 commit 中组件渲染时间由高到低的排名, 方便删选最长时间的渲染.
组件视图
如果你需要查看在你进行录制的过程中, 某个组件被渲染了多少次, 每次所用的时间, 那么这个视图就是为你准备的.
一看像一个柱状图, 每一条代表一次渲染, 长度和颜色代表时间的长短.
你可以通过双击一个组件, 或者选中一个组件, 点击右上角的图标来打开该视图.
互动?(Interactions 不知道怎么翻译好)
在之前 React 已经发布了一组实验 API 来追踪更新的原因, 使用这个 API 的信息也会在 devtool 中展示
途中四个绿点就是调用 API 的节点对应的 commit, 同时你也可以在火焰图的 commit 信息中看到在这个 commit 存在的活动追踪
你可以在互动和 commits 之间进行切换通过点击对应的信息
顺带提一下, 这个 API 通过 scheduler 这个包使用
- import { unstable_trace as trace } from "schedule/tracing"
- class MyComponent extends Component {
- handleLoginButtonClick = event => {
- trace("Login button click", performance.now(), () => {
- this.setState({ isLoggingIn: true });
- });
- };
- // render ...
- }
更详细的使用可以看这里
最后
这个功能非常棒, 它能够让开发者非常直观的看到他的每次操作带来的组件渲染消耗, 能够很方便帮助开发者发现一些不必要的渲染.
其实在 React 开发中一些小细节可能会给整个应用的性能开销带来很大的影响, 只是现在的浏览器太强大以及大部分应用都处于性能过剩的情况下, 所以性能问题不是特别明显.
在原文的最后有一个视频展示了如何利用 Profiler 帮助发现性能问题并优化的案例, 大家都可以看一下.
这个更新正好处于我正在阅读源码的时候, 所以我会在自己的源码分析里面添加进去, 源码分析的成果应该马上就好了, 如果大家有兴趣可以关注我.
来源: https://juejin.im/post/5ba1f995f265da0a972e1657