React 优化实践
背景
最近在用 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
的 ===
对比即可
- 对象或者数组,推荐使用 lodash
的 isEqual
函数,可以解决大多数情况下的比较
- 复杂的深层的对象或数组,采用 Immutable.js
去进行比较
- 特殊的,比如某些组件,如果组件的某个 key
不变(例如 id)就不进行更新,那我可以直接对比props
中我想要对比的这个属性即可
以上几种情况的前提,是在 Redux
中传递 state
的时候,对于对象或数组,使用 Object.assign
或者 Immutable.js
来传入一个新的引用,避免因为值不同但是引用地址相同,导致的错误比对。
key
如果你在 React
中使用了循环去渲染一系列组件(例如列表),React
会提醒你对每一个组件设置一个唯一的 key
。React
会根据这个 key
来判断组件的唯一性,如果两个 key
相同,则会只渲染一个组件。
其实这个 key
还有另外一个用途,就是判断组件是否需要 reRender
。React
会根据这个 key
值来生成该组件的唯一标识,如果下次渲染的时候 key
值不变(即使位置变了),则会复用该组件,只有产生了新的 key
值,才会渲染新的组件。所以,我们也可以利用这个 key
值来避免组件的不必要删除和创建,复用组件以达到性能优化的目的。
结语
基本上进行了以上的优化,页面打开速度有了一定的提升,关键是能清楚地知道页面没有进行不必要的 reRender
,在性能优化的路上前进了一步。