[Lv1] 图片加载优化:四层 Lazy Load
通过四层图片懒加载策略,将首屏图片流量从 60MB 降至 2MB,加载时间提升 85%。
问题背景 (Situation)
想象你在滑手机看网页,屏幕只能显示 10 张图片,但网页一次加载了 500 张图片的完整数据,你的手机会卡到爆,流量也瞬间烧掉 50MB。
对应到项目的实际情况:
📊 某页面首页统计
├─ 300+ 张缩略图(每张 150-300KB)
├─ 50+ 张促销 Banner
└─ 如果全部加载:300 × 200KB = 60MB+ 的图片数据
❌ 实际问题
├─ 首屏只看得到 8-12 张图片
├─ 用户可能只滚动到第 30 张就离开了
└─ 剩下 270 张图片完全白加载(浪费流量 + 拖慢速度)
📉 影响
├─ 首次加载时间:15-20 秒
├─ 流量消耗:60MB+(用户怨声载道)
├─ 页面卡顿:滚动不流畅
└─ 跳出率:42%(极高)
优化 目标 (Task)
- 只加载可视范围内的图片
- 预加载即将进入视窗的图片(提前 50px 开始加载)
- 控制并发数量(避免同时加载过多图片)
- 防止快速切换导致的资源浪费
- 首屏图片流量 < 3MB
解决方案(Action)
v-lazy-load.ts 实现
四层 image lazy load
第一层:视窗可见性检测(IntersectionObserver)
// 创建观察器,监测图片是否进入视窗
const observer = new IntersectionObserver(
(entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
// 图片进入可视区域
// 开始加载图片
}
});
},
{
rootMargin: '50px 0px', // 提前 50px 开始加载(预加载)
threshold: 0.1, // 只要露出 10% 就触发
}
);
- 使用浏览器原生 IntersectionObserver API(性能远胜过 scroll 事件)
- rootMargin: "50px" → 当图片还在下方 50px 时就开始加载,用户滑到时已经好了(感觉更顺畅)
- 不在视窗的图片完全不加载