周末的午后,窗外下着小雨,我像往常一样坐在咖啡馆的角落,面前摆着一杯热美式,屏幕上是刚写完的代码。最近在重构一个个人项目,发现页面加载速度有点慢,尤其是图片较多的页面。于是决定给项目加上图片懒加载功能,顺便记录一下实现过程。
为什么需要懒加载?
对于包含大量图片的页面(比如电商首页、作品集、博客列表),如果一次性加载所有图片,会导致:
首屏加载时间变长,影响用户体验
浪费用户流量(尤其是移动端)
增加服务器压力
懒加载(Lazy Loading)的原理很简单:只加载当前视口(viewport)内的图片,当用户滚动页面时,再加载即将进入视口的图片。这样既能提升首屏速度,又能按需加载资源。
实现方案对比
传统方案:监听 scroll 事件 + 计算元素位置
早期的做法是通过监听 scroll 事件,调用 getBoundingClientRect() 判断元素是否进入视口。但这种方式存在性能问题scroll 事件触发频繁,容易造成页面卡顿(通常需要配合 throttle 节流函数)。
现代方案:Intersection Observer API
现代浏览器提供了更高效的 Intersection Observer API,它可以异步观察目标元素与祖先元素或顶级视口的交叉状态。当元素进入或离开视口时,回调函数会被触发,而且不会因为频繁的 scroll 事件影响性能。
## 手写一个简单的懒加载
假设我们有这样的 HTML 结构:
<img class="lazy" data-src="real-image.jpg" src="placeholder.jpg" alt="lazy image">