如何顺滑的展现大数据列表?

往往谈到前端性能优化,大数据列表的呈现老是一个老生常谈的话题。基于浏览器自己处理DOM的方式,一旦列表数据足够大时,老是不可避免的出现CUP和内存占用致使的卡顿问题,所以,针对大数据列表,只能使用特别的方式来呈现。javascript

面对这个问题时,直觉反应就是切分:切成小块再呈现。好比,如今有10万条数据,仅仅拿出前1000条呈现出来,随着滚动条的滑动再逐步展现后面数据。然而,这种方式引发的列表高度变化会给用户带来很是糟糕的滑动体验,不管是补充数据仍是把原列表换掉,使用起来跟标准滚动条差异很是大。所以,仅仅是切分还远远不够。前端

定高

为了防止列表高度变化带来的滚动体验问题,须要在大列表呈现时就先计算好高度。也就是说当要呈现10万条数据时,即便只先呈现前1000条,10W条数据的总高度要先被算好并设置在最外层的容器上。目的是当滑动时,呈现的数据变化,但容器总高度不变,这样体验起来才会和普通滚动条一致。java

给10万条数据定高,就意味着你须要知道每一条数据呈现出来的高度是多少,在代码实现层面,能够拿出其中一条数据展现出来获取其高度。如此一来,不但总容器的高度能肯定,每一条数据在纵坐标的起始位置也能定下,为后续的滑动展现提供基础。node

经过单项定高

分组

一旦高度定下,就能够根据滚动条的的位置展现或隐藏列表数据,但具体的代码实现却不得不考虑性能问题,由于须要遍历整个列表逐个判断,10W条数据遍历一次也是特别大的运算,更糟糕的是,滚动条滑动的事件触发是很是频繁的。react

解决方案就是分组,即将100个或1000个划分为一组,以组为单位进行判断,同时,须要在定高时根据每一项高度计算出组的纵坐标起始位置。如此一来,遍历时以组为单位大大减小了计算量,10W条数据,1000个为1组,遍历起来也就只有100组而已。git

分组后,滑动展现时即可以灵活制定展现规则,好比滚动条划过当前组高度一大半之后展现下一组等。github

分组后的滑动展现预览图

分组算法

由于看了国外一篇写大数据列表的文章有感,才写了此文。值得一提的是,那篇文章中的分组方式很特别,利用二叉树算法,一个简洁递归就把数据分好了。算法

recursiveSplit =(data)=> {
    if(data.length / 2 > this.minimumStackSize) {
      let mid = Math.floor(data.length/2, 10);
      let node = { 
        parent: true,
        getParent: ()=> data,
        data: [this.recursiveSplit(data.slice(0, mid)), this.recursiveSplit(data.slice(mid, data.length+1))]
      }
      return node;
    }
    return {
      parent: false,
      data
    }
  }

做者最终Demo的效果如图,相关连接我已贴在文章底部。浏览器

demo效果展现图

结语

处理大数据列表的呈现,关键点有两个,一是定高,二是分组。定高保证了选择性呈现数据时滚动条的正常体验,分组则处理了频繁遍历带来的性能消耗。性能优化

参考资料:

https://medium.com/better-pro...

https://react-eternal-list.ri...

https://github.com/rinasm/rea...

相关文章
相关标签/搜索