在实现说说列表功能时,只想到了实现具体业务,没有考虑到长列表对性能的影响,每个说说组件都包含了复杂节点结构,大量的事件处理程序和动画等,每当加载新的一页时会造成组件累积,占据大量内存,在安卓中的表现是滑动极其卡顿,在ios中的表现是加载2、3页左右会出现小程序崩溃的情况,当快速滑动时小程序会黑屏。
导致崩溃、黑屏的原因经分析是因为内存占用过高,而导致内存占用过高的原因是因为说说组件累积,当加载新的一页时,前面的说说虽然已经不在需要,但是仍然会保留在内存中,对于移动端这种对内存限制要求高的设备会造成性能影响,因此最根本的办法是使用虚拟列表技术优化说说列表。
采用说说列表的核心思路是采用双数组的方式,一个数组存放所有说说,另一个数组存放需要被渲染的说说,以此来达到释放不再需要的说说组件的目的。但是要实现虚拟列表需要解决两个问题:
思路
采用页面滚动监听+定位的方式实现。通过监听onPageScroll
事件来获取滚动量,从而判断当前屏幕中应当出现哪些说说,但是这里有个问题每个说说组件的高度是不确定的,比如有些说说有9图片,高度就比普通说说高,因此不能直接计算说说的总高度与页面滚动量对比,这里的解决方法是为每个说说组件设置最小高度和偏移量,通过提前预判图片数量、文字个数来确定偏移量,也就是说说说的高度是最小高度+偏移量。
另外当前面说说组件释放后,由于页面流的作用,当前屏幕的说说会“塌陷上去”,造成窗口抖动,预想的解决方式是为第一条渲染说说设置定位,上面说说被释放的同时立刻计算第一条渲染说说应该出现的位置,然后通过position: relative + top
来设置定位,避免“页面塌陷”。
结果
采用此方案后
通过定位来防止窗口抖动很难实现,因为非常难计算
onPageScroll
事件触发太频繁,对性能消耗太大,此外在此事件进行大量计算可能会导致页面卡顿。
固定说说高度体验非常不好,而且偏移值难以计算,还容易出现bug,也不方便功能扩展。
思路
分析第一次失败的原因,原因有二: