使用 IntersectionObserver 延迟加载
直到图像和内容进入视口后再加载
使用 IntersectionObserver 延迟加载 是 CoddyKit 上的免费 HTML Academy 课时。 这是第 2 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 HTML Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 HTML Academy 课程共包含 4 节课。
超越原生延迟加载
原生延迟加载覆盖 <img> 和 <iframe>。对于其他内容——背景图片、视频、开销较大的组件以及第三方小部件——IntersectionObserver 是合适的工具,可以将这些工作推迟到元素接近视口时再执行。
实现模式
为需要延迟处理的元素添加 data-src 属性,并在其中保存真实来源;同时渲染一个很小的占位符。观察每个元素;发生交叉时,将 data-src 替换为 src(或以其他方式激活元素),然后取消观察,使回调不再触发。
<img class="lazy" data-src="/photo.jpg" alt="Photo" width="800" height="600">
<script>
const observer = new IntersectionObserver((entries) => {
for (const entry of entries) {
if (entry.isIntersecting) {
entry.target.src = entry.target.dataset.src;
observer.unobserve(entry.target);
}
}
}, { rootMargin: "200px" });
document.querySelectorAll(".lazy").forEach((img) => observer.observe(img));
</script>延迟加载背景图片
CSS background-image 原生不支持延迟加载。发生交叉时,设置 el.style.backgroundImage = `url("${el.dataset.bg}")`,或者添加一个定义 background-image 的 CSS 类。图片会在此时开始下载。
延迟加载视频
对于首屏以下的视频,初始状态下请省略 src 和 source 元素。发生交叉时,再注入 <source> 标签并调用 video.load()。否则,即使用户还没有滚动到元素附近,视频元数据也可能提前加载。
第三方小部件
社交媒体嵌入内容、评论小部件和聊天脚本可能会加载数兆字节的数据。发生交叉时,动态导入小部件的初始化脚本:await import("/embed.js")。只有当用户实际滚动到该区域时,才会产生这部分开销。
延迟加载 iframe(超越 loading="lazy")
原生 iframe 延迟加载仍然会下载 iframe 文档。对于地图、视频播放器等大型嵌入内容,请使用“外观层”模式:先显示占位图片;在用户点击或元素发生交叉时,将其替换为真实 iframe。这样可以大幅减少初始页面体积。
使用 rootMargin 预加载
rootMargin: "200px" 会在元素进入视口前 200 像素开始加载。请根据滚动速度进行调整:设置过小,快速滚动时用户会看到占位符;设置过大,则会因为加载所有内容而失去延迟加载的意义。
触发后取消观察
延迟加载激活后,请务必调用 observer.unobserve(element)。否则,每当元素重新进入视口时,回调都会继续触发,浪费 CPU;如果激活操作不是幂等的,还可能引发错误。
预留空间
为延迟加载的图片设置宽度和高度,并为延迟加载的容器设置最小高度。如果没有明确的尺寸,内容加载时页面会重新排版,从而造成令人烦恼的滚动跳动,并导致累计布局偏移分数变差。
无 JS 时的回退方案
如需实现完整的渐进式增强,请将带有真实来源的延迟元素放入 <noscript> 中:<noscript><img src="/photo.jpg"></noscript>。没有 JS 的用户会立即加载图片;有 JS 的用户则使用延迟加载版本。同时请配合正确的 data-src 标记。
批量观察多个元素
单个观察器实例可以高效地观察数百个元素。请不要为每个元素创建一个观察器。创建一个带有所需选项的共享观察器,并使用 observe() 注册每个目标。
与原生延迟加载结合
对于 <img>,请将 loading="lazy" 作为主要机制,并仅在原生延迟加载无法覆盖的情况下使用 IntersectionObserver。两者可以很好地结合:原生机制处理首屏以下的图片,IntersectionObserver 处理背景图片、组件和其他自定义加载器。
知识检查
延迟加载的元素激活后,为什么必须调用 observer.unobserve(element)?
总结
IntersectionObserver 将延迟加载的适用范围从原生的 <img loading="lazy"> 扩展到了背景图片、视频、第三方小部件和动态组件导入。请使用 data-src 占位符,在发生交叉时进行替换,并在激活后取消观察。使用 rootMargin 预加载,使用宽度和高度预留空间,提供 noscript 回退方案,并在适用时结合原生延迟加载。
常见问题解答
「使用 IntersectionObserver 延迟加载」课时是免费的吗?
是的 — 「使用 IntersectionObserver 延迟加载」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 HTML Academy 课程的其余内容,请升级到 CoddyKit PRO。 HTML Academy 课程共包含 4 节课。
「使用 IntersectionObserver 延迟加载」这节课中我会学到什么?
直到图像和内容进入视口后再加载 你通过在浏览器中直接运行的动手代码来练习 HTML Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 HTML Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 HTML Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 2 节课,共 4 节。
「使用 IntersectionObserver 延迟加载」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 HTML Academy 课中编写并运行代码吗?
能。每节 HTML Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- IntersectionObserver API 与阈值
- 使用 IntersectionObserver 延迟加载
- 实现无限滚动
- 设置滚动关联动画