当一个页面需要展示的数据量较大时,为了使用户获得最佳使用体验,我们常选择分页的方式进行展示数据,减少单次显示数据来降低服务器响应时间以及页面渲染时间,从而降低页面首屏时间。
PC 端常见两种交互方式,通过分页控件的方式,用户点击下一页或指定页数进行跳转,另一种是通过懒加载的方式,通过监听页面滚动,在页面内容快展示完时请求下一页的数据并 append 到页面中。
而在移动端,我们更想让用户无感知地浏览到页面最后一页,保证了信息阅读的连续、流畅,既然这样,滚动懒加载的方式处理分页就成了不二之选。
备注:默认引入 jQuery/zepto
监听滚动
页面中,在文档底部到视窗底部的距离低于某个阈值时,触发下一页数据请求,我们这里设置距离低于 200px 时,触发请求。
现在已经完成了最基本的功能需求,但因为绑定的 scroll 事件,页面滚动时就会触发,因此,内容底部和视窗底部的距离小于 200px 时,页面继续滚动,loading 会被继续触发,这就丧失了分页的意义,所以在这里需要对加载的触发进行稀释。
事件稀释
我们设定一次请求触发后,需保持 60ms 安静,即这 60ms 不会出现二次触发请求事件,以保证这是一次稳定的请求触发。假设第一次触发的 60ms 内被被第二次触发,第一次作废,从第二次重新开始计时 60ms。
稀释后,触发条件间接变成在页面滚动停止时,发出数据请求。但一个新问题出现,如果请求返回稍慢,用户等不及,一直在页面底部摩擦摩擦,导致请求被多次发出,并且异步请求返回的顺序可能打乱原有数据顺序,第 2、3 页请求发出去,返回的数据顺序可能先是第 3 页再是第 2 页,这时候就该给请求加把锁。
事件锁
通过给请求添加 loading 状态,同一时间只允许一个请求执行,当已存在未返回请求时,新的请求不会被触发。
UI 优化
作为开发者,我们清楚知道触发数据加载的过程,清楚触发的时机以及请求的过程,但用户看到的只是页面拉到了底部(请求还没响应),用户以为已经显示全部数据了,实际只是分页数据还没加载出来,等页面真正看完全部数据,用户却可能认为还会有下一页,不断上拉页面,试图拉出隐藏于某处的一些数据。
一个用户体验优秀的前端页面,应该具有准确传递信息的能力,这些功能实现成本很低,但可以带来更好的用户体验。
所以,在数据加载时,在页面底部添加一个加载的 GIF 动画,缓解用户的焦虑,“放轻松,系统正全力加载中~”,数据加载到最后一页时,用户还准备上拉加载时,发现加载 GIF 被 “到底了~” 文案取代。
容错处理
程序不可能 100% 依照我们编写的逻辑运行,上面介绍的内容都是在数据正常返回的情况下,如遇到接口异常时,请求没有拿到想要的数据,请求已经返回错误,通过在将加载动画替换为重新加载的点击按钮,通过用户点击触发二次请求。
scroll 兼容问题
scroll 目前仍存在兼容问题,视 webview 而定,iOS 7 及之前在 scroll 时会暂停 CSS3 animation 和 javascript 运行,但一些 APP 内定制的 webview 仍会存在这样的问题,所以,在实现相同需求前,请花一点时间验证。
以上,就是我在做滚动加载过程中的一点总结,辛苦期间启蒙大大、顾老师、宇航大大不厌其烦的解答。
本文转载自公众号贝壳产品技术(ID:gh_9afeb423f390)。
原文链接:
https://mp.weixin.qq.com/s/83euut430ZGn-crgqMW3cA
评论