文章结构
文章基本思路:“目的 => 方案 => 验证 => 总结启发”
一,图片懒加载实现
二,预期效果
三,A/BTest验证
四,总结
一,图片懒加载实现
实现图片懒加载的目的是在不影响用户体验的前提下,尽可能节省用户流量甚至是电量。(可以参考Why lazy load images or video instead of just loading them?)
方案选择
图片懒加载的本质是将某一图片的加载推迟到用户看到或即将看到该图片的时候。实现图片懒加载目前有三种方案:
方案 | 具体描述 | 缺点 |
---|---|---|
一. 小程序image组件的lazy-load属性 | 小程序 - image | ①不支持配置(加载时机,预加载数量) ②仅在page和scroll-view中生效(意味着很难通用) |
二,页面滚动监听 | 小程序页面监听页面滚动(onPageScroll),滚动时逐一比较图片节点的top值(可由wx.createSelectorQuery().select('yourselector’).boundingClientRect((ret)=>{}).exec() 获得)与滚动位置的关系 |
监听滑动 & 遍历所有节点会对滚动性能产生一定的影响(如果节点从上到下遍历,能做一些优化,也能达到较好的效果) |
三,IntersectionObserver | 采用IntersectionObserver API,交由浏览器内核底层判断图片是否与视窗相交,减少内核层与js层的跨进程通信,性能更好(小程序基础库1.9.3开始支持) | 不兼容低版本浏览器内核 |
补充:
①除了方案一,方案二三都同时支持小程序和H5,这里仅以小程序为例。
②如有别的方案欢迎分享补充_
基于上面的方案分析和当前用户系统占用率分布(IntersectionObserver API支持率大于80%),我决定采用IntersectionObserver API来对当前项目做渐进式增强,后续随着用户设备更新,将能实现100%的优化覆盖。
方案实现
参考性能更优越的小程序图片懒加载方式,感谢分享!注意:原文章方案存在Android快速滚动到底部没有触发加载 的问题。
从前面的视频我们可以看到,优化的对象是商品详情图片列表,考虑到复用性,我把图片列表封装成lazyload-list
组件,源码如下:
/**
* lazyload-list
* imgs: 图片链接数组,
* lazyload: 是否开启lazyload功能,默认开启
* <lazyload-list imgs="{
{intros}}"></lazyload-list>
*/
Component({
properties: {
imgs: {
type: Array,
value: [],
},
lazyload: {
type: Boolean,
value: true,
}
},
data: {
lazyImgs: [],
classNote: 'lazy-img-'
},
ready: function() {
// 接口兼容性判断,不支持新特性则回退到即时加载的方案
if (!this.createIntersectionObserver) {
// @TODO 可以改用基于滚动检测 & 高度判断的实现方案
this.setData({
lazyload: false });
} else {
var lazyImgs = [];
this.data.imgs.forEach(function(img) {
lazyImgs.push({
url: img,
loaded: false
})
}