长列表优化——虚拟列表

2020-04-18  本文已影响0人  依然还是或者其他

前言

场景是小程序长列表优化,框架基于mpvue,固定高度。(动态高度暂时先不考虑)

关于recycle-view

微信官方的提供的recycle-view,是原生的小程序组件。但如果你是基于mpvue框架的话,对第三方原生组件可能不太友好——花了很多时间,最终也没有个所以然,所以就改方案自己来好了。
如果你想要尝试的话,下面的一些坑可以看下:
1.这里是mpvue官方对于第三方原生组件的建议,mpvue官方是建议原生和mpvue做分离(ps:感觉很麻烦)。如果只是想引入第三方原生组件,做法可以参考这里
2.在完成引入第三方组件后,如果直接按官方文档的写法,会出现 page.selectComponent is not a function的报错,因为mpvue的this和原生的this指向不同,所以应该使用this.$mp.page
3.后面出现了调用append后页面没内容的情况,也没的办法了,在看了recycle-context源码和社区后,还是算了吧
(ps:源码内部其实是利用page自身的forceUpdate,来强制刷新;社区也有类似的问题,但没人解答;出于时间考虑,就没用这个了;说不定思路在recycle-view其他源码上😅)

如果有人弄出来了,请留言指导,感谢大佬。

回到虚拟列表

大致原理:
控制滚动元素可滚动区域中的位置,使其显示在可视区域

假设手机为375667, 有1000条条数据需要渲染,每条高60, 滚动元素区域
那么 滚动元素区域有60
Math.ceil(667/60),可滚动区域 为 100060,可视区域* 为667

大体步骤为:
1.通过触发scroll滚动事件,计算出startIndex、endIndex
2.根据starIndex、endIndex计算出滚动元素区域
3.根据starIndex、endIndex计算startOffset、endOffset
4.渲染


虚拟列表1.png

实际在DOM实现上有两种思路:

<div class='wrapper'>  //可视区域
        <div style='padding-top: xx px, padding-bottom:  xx px'> 
          //滚动区域
        </div>
</div>
<div className='wrapper'>  //可视区域 position:relative
  <div className='list'></div>  // 可滚动区域
  <div className='visible-list' style="transform: translate3d(0, XX px, 0)"></div>  //元素区域  position:absolute
</div>

推荐使用第二用,translate3d可开启硬件加速,提升渲染性能

关于动态高度

还没实践过,后续再补充

参考:
1.浅说虚拟列表的实现原理
2.再谈前端虚拟列表的实现
3.前端长列表原理及优化
4.长列表渲染实践
5.一个简单实现的vue虚拟列表

上一篇下一篇

猜你喜欢

热点阅读