真正要做的不是删除非关键标签,而是让浏览器“知道哪些可以晚点理”;原生loading="lazy"仅对和有效但行为不同,非首屏须用data-src+IntersectionObserver控制,和则需通过defer、onload等机制干预加载时机。

为什么直接删掉非关键标签反而更慢
浏览器解析 HTML 是单线程、自上而下进行的,但“删掉”或这类标签并不等于提升性能——如果它们本该在首屏外,却写在 HTML 早期位置且没做任何控制,浏览器会在解析到那一刻就发起请求、抢占带宽、触发布局计算,甚至阻塞 DOM 构建(尤其对)。真正要做的不是删除,而是让浏览器「知道哪些可以晚点理」。
loading="lazy" 对哪些标签生效、怎么加才起作用
原生 loading="lazy" 仅对 和 有效,但行为差异极大:
-
:Chrome 76+ / Firefox 75+ 支持,只要在初始视口外(getBoundingClientRect().top > window.innerHeight),就会延迟加载;首屏图必须显式去掉该属性,否则可能空白 -
:规范强制首屏内 iframe 必须 eager 加载,loading="lazy"完全无效;即使写了,Chrome 也会忽略并立刻请求,Safari 15.3 及更早、Firefox 当前版本(2026)也都不支持 - 所有加
loading="lazy"的必须带width和height属性(或 CSSaspect-ratio),否则加载瞬间会引发 CLS - 别同时写
src和loading="lazy"再用 JS 监听——浏览器可能先加载src,导致重复请求
非首屏 怎么真正延迟加载
不能靠 loading="lazy",必须用 data-src + IntersectionObserver 主动控制:
- HTML 中彻底移除
src,只留占位结构,比如: -
IntersectionObserver的rootMargin设为"0px 0px 300px 0px",提前触发,避免用户看到边框才开始加载 - 回调中把
data-src赋给src后,立刻调用observer.unobserve(iframe),防止滚动反复触发 - 务必监听
iframe.onload再更新状态;若需 postMessage,得额外判断iframe.contentWindow是否可访问(跨域时为 null)
<script></script> 和 的延迟解析逻辑完全不同
这两类资源不靠“懒加载”,而是靠加载时机和优先级干预:
-
<script></script>:同步脚本(无defer/async)会暂停 HTML 解析;非关键脚本一律用defer(按序执行、DOM 就绪后触发),统计类可用async(下载完即执行,不保序);type="module"默认等效defer,但注意旧版 Safari 兼容性 -
:外部 CSS 默认渲染阻塞,浏览器必须构建完 CSSOM 才能绘制;非关键样式应延迟加载,推荐写法:,利用onload切换媒体类型来绕过初始阻塞 - 绝对禁用
@import引入关键样式——它强制串行请求,比多一次网络往返,实测拖慢 FCP 300ms+
最容易被忽略的是:首屏是否真需要某个资源,不能只看“它在不在视口里”,还得看它是否参与首屏渲染路径。比如一个隐藏的 却在 里声明了 src,照样会阻塞解析——浏览器不看 display,只看是否出现在初始 HTML 流中。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











