性能优化之虚拟列表

在前端开发中,UI渲染一直都是重头戏。

我们可以回想一下,通常我们将一个DOM节点渲染到页面上,通常采用的方式有以下两种

  • innerHTML
  • appendChild

这两种DOM渲染的方式之间的对比,网络上有很多分析的文章,这里不再赘述

总的来说,两者对性能的影响差异不大,可以忽略不计

既然对性能影响不大,那我们还讨论什么呢?

我们在开发的时候,通常遇到这个场景,后端返回json格式的数据,前端拿到数据自然是渲染,当然在渲染前可能会作一些处理

如果数据量小的话,那还好办直接对数据进行循环遍历就是了;问题是当返回的数据量很大时,我们该怎么办?

特别是在移动端,对于性能的要求比较高,如果将大量的数据一次性渲染出来,很可能会出现卡死、白屏、甚至浏览器会崩溃

我们常见的做法是延迟加载,或叫无限滚动,原理也就是根据滚动条滚动的距离,来判断用户浏览当前网页的位置,监听滚动事件,从而当滚动条到达合适的距离,触发回调向后端发起请求,后端返回数据后再渲染出来

这种解决问题的思路是从数据入手,也就是对数据进行几次分割,每次只是请求部分数据,这样渲染的压力就减小很多

传统PC端的分页也是相似的原理,区别只在于分页会导致页面全部刷新,而无限滚动只是局部刷新,后者用户体验更好

我们今天的主角:虚拟列表。它所要解决的问题也是前面提到的大量DOM渲染开销大的问题,区别于上面的解决手段,它的思路是从UI入手

它的原理是这样的:当我们在浏览网页时,其实看到的只是浏览器视窗范围的内容,超出视窗的内容我们是看不到的

那既然这样,我们在渲染DOM时,就只需要渲染用户当前看的部分,其他的都可以不用渲染了

说到这里,我们就知道要实现虚拟列表,很关键的一点就是高度问题。这里的高度包括浏览器视窗的高度,列表每一项的高度。根据这些高度,我们才可以判断究竟要渲染列表中的哪一项到哪一项。

当时要用到公司的业务中,肯定需要借助市面上成熟的类库,因为技术栈是React,所以这里以react-virtualized为例,来分析其具体技术实现