React 优化实践

Author Avatar
Splendour 8月 01, 2016

背景

最近在用 React + Redux + WEUI 做一个企业号上的企业系统移动端版本,发现在性能较差的手机上还是有蛮大的卡顿,故开始查找资料想办法进行优化。

why-did-you-update

无意中看到某大神 Star 了这个项目,一开始还没有特别注意,后来在某博文上又看到该工具的推荐。该工具可以在你的组件每次 reRender 的时候,对比该组件的 props,如果没有变化,会告诉你这是不必要的 reRender点此进入项目
工具的使用也特别简单,只需要在前端主文件中加入一句话,装饰一下 React。

import React from 'react';
const {whyDidYouUpdate} = require('why-did-you-update');
whyDidYouUpdate(React);

重新打开页面,发现加载了很久,这是由于 why-did-you-update 在浏览器上打印了很多的信息。不看不知道一看吓一跳,原来在我渲染页面的时候做了这么多无谓的 reRender 操作,真是浪费性能!

ShouldComponentUpdate 优化

那么多的 reRender,要怎么避免呢?
对于无状态组件来说,只需要重新实现该组件的 ShouldComponentUpdate 方法即可。
ShouldComponentUpdate 默认返回的是 true,即默认当有新的 props 传入时,就执行 reRender 操作。我们要做的就是对比前一个 props 和新传入的 props,来决定是否返回 true 让组件更新。这里分几种情况:

- 简单的字符串或者数字,直接使用 JavaScript=== 对比即可
- 对象或者数组,推荐使用 lodashisEqual 函数,可以解决大多数情况下的比较
- 复杂的深层的对象或数组,采用 Immutable.js 去进行比较
- 特殊的,比如某些组件,如果组件的某个 key 不变(例如 id)就不进行更新,那我可以直接对比props 中我想要对比的这个属性即可

以上几种情况的前提,是在 Redux 中传递 state 的时候,对于对象或数组,使用 Object.assign 或者 Immutable.js 来传入一个新的引用,避免因为值不同但是引用地址相同,导致的错误比对。

key

如果你在 React 中使用了循环去渲染一系列组件(例如列表),React 会提醒你对每一个组件设置一个唯一的 keyReact 会根据这个 key 来判断组件的唯一性,如果两个 key 相同,则会只渲染一个组件。
其实这个 key 还有另外一个用途,就是判断组件是否需要 reRenderReact 会根据这个 key 值来生成该组件的唯一标识,如果下次渲染的时候 key 值不变(即使位置变了),则会复用该组件,只有产生了新的 key 值,才会渲染新的组件。所以,我们也可以利用这个 key 值来避免组件的不必要删除和创建,复用组件以达到性能优化的目的。

结语

基本上进行了以上的优化,页面打开速度有了一定的提升,关键是能清楚地知道页面没有进行不必要的 reRender,在性能优化的路上前进了一步。