首页feed流滑动实现图片预加载和数据无感加载方案

RecycleView优化

Posted by Tristan on March 9, 2022

背景

  1. 内容时代已来,很多APP都在用feed流的形式展示内容;同时呢,现如今又是一个存量用户的时代,各家APP对自身的用户体验越发重视。feed流无感加载,可以免除用户等待请求数据的时间,对提升用户浏览体验将会起到引领的作用。
  2. 列表控件通常提供三种状态给开发者使用,分别是:拖动态、滑动态和闲置态。通常,为了减少不必要的性能损耗,列表处于滑动态时不加载图片。但是,列表的滑动过程是一个由快到慢的过程。当列表在慢下来时,用户即将所见的内容其实可以视为有效浏览的。

图片预加载方案

现有方案

当列表处于滑动态时图片不会加载(滚动过快时视为无效浏览);只有列表被拖动时加载图片,或者滑动停止后处于闲置态再加载图片。

流程图:

代码实现:

缺陷:用户每次滑动后,页面在滚动未停止前feed都是不显示图片的,只有页面滚动停止后等图片加载完毕才可以看到图片。从滑动开始到停止后图片加载完毕,这个阶段是一个列表从快到慢的滚动过程,整个过程页面图片空白率是100%,页面即便在慢下来时图片区依然是空白的(如下图所示)。

预加载方案

给列表控件增加一个“将停”态,待列表滚动变慢进入这个状态时提前加载图片。

技术实现:重写列表控件的onScrolled(int velocityX, int velocityY)方法,其中velocityY表示垂直方向滑动速度。当列表处于滑动态时,计算滑动速度是否小于设定的阈值,如果小于的话则把列表状态改为“将停”的状态,同时通知状态已变更。编码如下:

新增状态之前,只会在拖动态和闲置态加载图片;新增状态之后,在新的“将停”状态下也开启图片加载。

将停状态下的效果图:

小结

给列表增加一个将停的状态,本质上是给列表提供了一个预处理的时机,让列表赋有了预加载能力。在将停态触发图片加载,当列表滚动变慢时图片也能及时显示,从而减少了正常视觉上的页面空白率,起到有效提升用户体验的作用。

数据无感加载方案

现有方案

当列表滑动到最后一项,给用户展示一个文案或动画,示意程序正在请求下一页数据;待程序请求新数据完成后,取消展示的提示文案或动画,然后把新的一页数据追加载到列表。

  

缺陷:用户每次浏览到列表底部需要等待新的数据请求完成(动画结束)后才能继续上滑浏览更多信息。

流程图:

代码实现:

无感加载方案

提前请求下一页数据并加载,同时限制列表的最大滑动速度,双举确保列表滑动到原有内容的最后一项时请求已完成加载。

1)提前请求下一页数据并加载,用程序化的思路设计——当列表滑至倒数第n项时开始请求新数据。

2)滑动是一个由快到慢的减速运动,限制最大滑动速度其实是限制了滑动的初速度。

除此之外,为了不过分限制滑动的速度,同时又保证提前加载数据,特意为RecycleView的滑动添加了一个临界态,这样可以多一次预判的时机,整体流程上将会保持一个均衡的参数配置。

代码实现1:

代码实现2:

小结

本方案为滑动列表控件提供了一套数据加载时机完全可配的方案,开发者通过设置两三个关键参数,完全可以实现feed流滑动过程中数据的无感加载,从而免除了feed流滑动浏览过程中的等待时间,将有效提升APP的使用体验。

整体效果

总结

  1. 通过自定义列表控件,给列表增加一个新的将停态,为列表控件赋能,让列表有了预加载机制。这个预加载机制,既可以保证滑动过程中不过度开销性能,又可以让图片及时显示。
  2. 通过三个维度(滑动位置、滑动速度、滑动状态)的综合实现和参数配置,有效的把数据加载时机控制在了列表滑动触底之前,从而在产品策略上实现了feed流无感知加载数据的能力。