在React中优化渲染一组元素的技巧
原文链接(请配合原文阅读,部分框架推荐文中没有)
这是一篇提升React性能的指南. 这个高级技巧会使其提速20倍。 对于几乎所有web-app来说,在一个页面渲染一些元素的列表是家常便饭。 在这篇文章中,我将展示如何在这种情况下提升性能。
我们将创建一个在canvas元素中绘制一组目标(圆圈)的app来当作测试样本。我将使用Redux来进行数据存储。但是这些技巧也可以应用在许多其他的状态管理方法中。当然了你也可以搭配react-redux来使用这些技巧,但为了更好的解析我不会用它。
让我们从存储的定义开始。
然后定义我们应用程序的渲染。对于画布渲染我将使用 react-konva。
这个应用程序的结果是:
现在让我们创建一个将要在一个目标上运行多个更新的简单测试脚本:
让我们在没有优化的app中运行测试脚本。在我的机器上,一次更新大约花21ms。
无优化渲染所花时间
这个时间并不包括绘图画布, 而只有redux + react 代码因为 react-konva 只在下一帧动画开始时绘制对象。我们现在对canvas的优化并不感兴趣, 它可以是另一篇文章的主题。
所以更新1000个元素花了大约21ms是相当不错的表现了。如果我们更新的元素很少我们就能保持代码原样。
但是我在有的地方需要频繁的执行更新(在拖放期间每一个鼠标动作)。对于60 FPS 的动画, 每次更新所花的时间不能多于 16ms.所以对于这种情况21ms不太令人满意(附加将会有绘图画布)。
那么我们怎样进行优化渲染呢?
1 不要更新未更改的元素
这是提升React性能的第一守则。我们所需要做的是对目标元素实施shouldComponentUpdate
:
更新结果 (http://codepen.io/lavrton/pen/XdPGqj):
使用经典优化渲染所用的时间
哇哦!~4ms vs 21ms。这已经好很多了。但我们可以做的更多吗?在我真正的app里即使有这次优化,它的性能依然很差。
高级调优
现在让我们看看App组件中的“render()” 函数。在这代码中让我有点不爽的是app组件里的render()
每次更新都会被唤醒。
这意味着对于每个目标来说 React.createElement 会被唤醒超过1000次。在这种情况下, 它的工作速度虽然很快但在大型应用程序中可能会变得很慢。
如果我们知道只有特定的组件会更新为什么我们还要渲染整个列表呢? 我们能不能直接对其进行更新?
2 使子组件更高明
方法很简单:
当一个列表中的元素的数量和顺序相同时,不要更新app的组件
如果数据改变的话,子组件需要自动更新
所以 “Target” 组件要被订制用来存储和跟踪改变:
对App组件实施 “shouldComponentUpdate” :
改变之后的结果(http://codepen.io/lavrton/pen/bpxZjy):
使用高级优化渲染的时间
对于一次更新来说0.25ms就好很多了。
额外的技巧
使用 https://github.com/mobxjs/mobx 来跳过这些订制代码。同样应用程序使用 mobx (http://codepen.io/lavrton/pen/WwPaeV):
使用mobx态渲染所花时间
大约是之前结果的1.5倍(如果你有更多元素的话差别会更大),同时代码更简洁。
译文出处:https://www.zcfy.cc/article/tips-to-optimise-rendering-of-a-set-of-elements-in-react
共同学习,写下你的评论
评论加载中...
作者其他优质文章