1. 主页 > 好文章

手把手教你用Intersection Observer实现懒加载,兼容PC 移动双端

(抓耳挠腮)上周隔壁运营小妹跑来问我:"为啥我们电商站的手机端,用户划到第三屏就开始卡顿?"我打开控制台一看——好家伙!瀑布流页面同时加载87张高清图,这能不卡吗?今天咱们就用真实案例,教你用浏览器自带的"侦察兵"解决这个顽疾。

▌先看问题现场
假设你正在开发一个服装商城,移动端瀑布流每屏显示4张图,PC端则是6列布局。用户反馈说:"滑动时总感觉一顿一顿的,特别是安卓旧机型"。这时候打开Chrome的Network面板,你会发现——用户刚进入页面时,所有图片都在疯狂加载!

(拍大腿)问题就出在这儿!用户根本看不到第20张图,为什么要提前加载?这时候就该请出Intersection Observer这个神器了。

▌实战步骤分解
假设你的图片标签现在是这样的:

html运行复制
src="placeholder.jpg" data-real-src="product-1.jpg">

第①步:初始化侦察兵

javascript复制
const observer = new IntersectionObserver((entries) => {
  entries.forEach(entry => {
    if(entry.isIntersecting) {
      const img = entry.target
      img.src = img.dataset.realSrc
      img.removeAttribute('data-real-src')
      observer.unobserve(img) // 停止监视已加载的
    }
  })
}, {
  rootMargin: '200px 0px' // 提前200px加载
})

第②步:处理双端差异
PC端因为有多列布局,得加上横向检测:

javascript复制
rootMargin: '200px 200px' // 左右各预留200px

第③步:绑定所有图片

javascript复制
document.querySelectorAll('img[data-real-src]').forEach(img => {
  observer.observe(img)
})

(突然想到)你可能会问:要是用户快速滑动,图片来不及加载怎么办?这时候就需要在placeholder.jpg上下功夫。建议用超小尺寸的模糊图占位,比如把原图压缩到10px宽,再用CSS模糊效果。

▌遇到兼容性怎么破?
某天测试突然报障:"老板的iPhone6打开图片不加载!"查兼容表才发现,iOS12以下不支持Intersection Observer。别慌,咱们分情况处理:

情况解决方案优缺点
现代浏览器原生API性能最优
老旧设备改用scroll事件耗电但可用
折中方案加载polyfill增加30KB体积

推荐这样动态适配:

javascript复制
if ('IntersectionObserver' in window) {
  // 用高级方案
} else {
  // 降级为滚动检测+节流
}

▌真实效果对比

改造前改造后
首屏加载3.2秒首屏1.4秒
CPU峰值占用87%最高62%
华为Mate10滑动卡顿流畅跟手

小编观点:别再手动计算scrollTop了!2024年就该用浏览器原生方案,既省事又不容易出bug。就像给网站请了个智能警卫,它会自动帮你盯着该加载的区域,双端适配无非就是调整侦察范围的事儿。

本文由嘻道妙招独家原创,未经允许,严禁转载