Chinaunix首页 | 论坛 | 博客
  • 博客访问: 471231
  • 博文数量: 153
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 1575
  • 用 户 组: 普通用户
  • 注册时间: 2016-12-20 17:02
文章分类

全部博文(153)

文章存档

2017年(111)

2016年(42)

我的朋友

分类: Java

2016-12-29 16:00:30

前言

用 React 一段时间了,也做了不少列表页。在用 React 做无限下拉加载的列表页时发现个问题:页面前几页渲染速度还挺快的,但是越往下拉加载内容页面的渲染就越慢。这是怎么回事呢?
让我们先来看下 React 的组件渲染流程吧。

React 的组件渲染流程

React 的组件渲染分为初始化渲染和更新渲染。在初始化时,React 会调用根组件下所有组件的 render 方法进行渲染。

在每个生命周期更新时,React 会先调用 shouldComponentUpdate(nextProps, nextState) 方法来判断该组件是否需要更新。该方法会返回 true 或 false 来表示更新或不需要更新。如果不需要更新,则直接保持不变;如果需要更新,则调用 render 方法生成新的虚拟 DOM,然后再用 diff 算法与旧的虚拟 DOM 进行对比,如果结果一致就不更新;如果对比不同,则根据最小粒度改变去更新 DOM。
整个过程如下图所示。

ShouldComponentUpdate 在默认情况下返回的是 true。也就是说 React 默认会调用所有组件的 render 方法生成虚拟 DOM,然后再与旧虚拟 DOM 比较以确定最终组件是否需要更新。这个 render 和 diff 对比的过程对于只是兄弟组件发生了改变,而本身并没有变化的组件来说,很明显存在资源浪费。

那么如何能直观的知道这些浪费都发生在哪些过程中呢?这就轮到 Perf 出场了。

接下来让我们先来了解下什么是 Perf,再看看它都能做些什么。

什么是 Perf ,它能做些什么?

 是 react 官方提供的性能分析工具,可以对我们的应用进行整体性能分析并提供性能数据。
直接来看下具体有哪些 API 吧:

  • Perf.start():开始测量。
  • Perf.stop():停止测量。
  • Perf.getLastMeasurements():在停止测量之后调用,用来获取 measurements。

接下来就可以打印出性能数据了:

  • Perf.printInclusive(measurements):打印出所花费的整体时间。
  • Perf.printExclusive(measurements):打印出处理 props、getInitialState、调用 componentWillMount 和 componentDidMount 等的时间,这里面不包含 mount 组件的时间。
  • Perf.printWasted(measurements):打印出测量时段内所浪费的时间。这部分信息是分析数据中最有用的一部分了。我们可以通过这个数据找出时间被浪费在了哪儿。浪费一般出现在组件没有渲染任何东西的时候,如上文中提到的,组件在 render 出新的虚拟 DOM 和旧的虚拟 DOM 对比之后,发现不需要更新组件。最理想的情况这个的返回值是一个空数组。
  • Perf.printOperations(measurements):打印出分析时段内发生的底层 DOM 操作。

目前不少 React 性能优化的文档里都有提到可以通过 shouldComponenentUpdate 和 Perf 来进行优化,但是却没有进行详细的说明。一开始的时候我是困惑的:

  • Perf 是怎么跑起来的?
  • 在什么时候执行比较好?
  • 性能报表中的各个指标是什么意思呢?
  • 怎么结合这些数据来进行优化?

翻了不少文档并实践之后,以我们到家业务的店铺列表组件的优化为例,总结出来了以下的使用步骤,仅供大家参考。

Perf 怎么用?

使用步骤:

步骤一:获取

  • 先在页面把原来的 react.js 替换成带组件的版本 react-with-addons.js
    • 这里要补充说明下关于使用的 react-with-addons 的版本
    • 推荐使用最新版本 15.3.2。
    • 如果使用 15.1.0 版本,react-with-addons 有可能会出现 Warning: There is an internal error in the React performance measurement code. We did not expect componentWillMount timer to stop while no timer is still in progress for another instance. Please report this as a bug in React。另外会出现有时候执行 React.addons.Perf.printOperations(measurements); 打印不出信息来等一些奇怪的问题。
    • Perf 是在  中新增的, 然后在 [15.1.0 版本]中进行了重构,并在后续版本中修复了不少 bug,目前还在逐渐完善的过程中。另外要注意的是:在非生产环境是不能使用 Perf 的。

阅读全文请点击:
阅读(2227) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~