Skip to content

参考

基于 MDN(Intersection Observer / Speculation Rules)、web.dev(Browser-level image lazy loading)、Vue Router 官方文档、Chrome for Developers(Prerender pages)+ webpack 魔法注释官方说明编写

速查

  • <img loading>lazy(视口外延迟)/ eager(默认);仅 JS 启用时延迟;不支持 CSS 背景图
  • IntersectionObserverroot: nullrootMargin: '200px 0px'threshold: 0 + unobserve()
  • Vue Router 路由懒加载component: () => import('./View.vue')(不要套 defineAsyncComponent
  • webpack 魔法注释/* webpackPrefetch: true */(未来导航、低优先级)/ /* webpackPreload: true */(当前页、高优先级)
  • Speculation Rulesprefetch(仅文档响应)/ prerender(完整渲染);eagerness 四档;默认 list→immediate、where→conservative
  • Chrome 并发上限:immediate 档 50 prefetch / 10 prerender
  • Chromium-onlyHTMLScriptElement.supports('speculationrules') 检测 + <link rel="prefetch"> 回退;CSP 'inline-speculation-rules'
  • 完整说明见 入门 / 深入指南

loading 属性表

元素取值行为
<img>lazy视口外延迟加载
<img>eager(默认)立即加载,等价不写
<iframe>lazy视口外延迟加载
<iframe>eager(默认)立即加载
CSS background-image不支持 loading 属性,需用 IO

五个关键事实

事实说明
仅 JS 启用时才延迟禁用 JS 时正常加载(web.dev 明确)
不支持时不报错旧浏览器忽略属性,正常加载(优雅降级)
必须写 width/height不写会 CLS,或被判定 0×0 全在视口内全量加载
<img> / <iframe>背景图、<video><source> 都不支持
iframe 支持较晚Firefox 121 / Safari 16.4 才齐,晚于 img

IntersectionObserver API 速查

构造器与字段

ts
new IntersectionObserver(callback, options);

const options = {
  root: null, // 祖先元素,null = 视口
  rootMargin: "200px 0px", // 围绕 root 的边距,正值=提前触发
  threshold: 0, // 0~1,目标可见比例阈值
};

实例方法

方法作用
observe(target)开始监听目标元素
unobserve(target)停止监听单个目标(懒加载常用)
disconnect()停止监听所有目标并释放
takeRecords()立即取出待处理回调(罕见用)

回调 entry 常用字段

字段含义
entry.target被监听的元素
entry.isIntersecting是否相交(懒加载判断条件)
entry.intersectionRatio相交比例(0~1)
entry.boundingClientRect目标边界矩形
entry.rootBoundsroot 边界矩形

懒加载场景惯例

字段推荐值原因
rootnull相对视口
rootMargin"200px 0px""25%"提前预取,避免滚到时看到空白
threshold0任何像素进入即触发
回调内observer.unobserve(target)加载完释放

Vue defineAsyncComponent 选项表

字段类型作用
loader() => Promise<Component>加载函数,典型 () => import(...)
loadingComponentComponent加载中显示
delaynumber(ms)显示 loading 前的延迟,防闪烁
timeoutnumber(ms)超时时间
errorComponentComponent加载失败显示
onError(err) => boolean | Promise<boolean>失败回调,返回 true 重试

Vue Router 路由用 component: () => import(...)不要defineAsyncComponent 用在路由组件上(官方明确反对)。

webpack 魔法注释表

注释生成优先级时机用途
/* webpackPrefetch: true */<link rel="prefetch">浏览器空闲时未来可能跳转的 chunk
/* webpackPreload: true */<link rel="preload">与当前 chunk 并行当前页必用的晚发现 chunk
/* webpackChunkName: "x" */命名/分组 chunk

Speculation Rules API 速查

prefetch vs prerender

动作做什么子资源代价适用
prefetch仅下载文档响应不含加速下一页 TTFB
prerender完整渲染(含 JS 与数据 fetch)大(CPU/内存/流量)高概率跳转,激活近乎瞬时

eagerness 四档触发时机表

触发时机默认用于
immediate命中规则即拉urls 列表规则(默认)
eager鼠标 hover 链接高概率跳转
moderatepointerdown 按下中等概率
conservativepointerdown 且有犹豫(按下到抬起间隔)where(document) 规则(默认)

Chrome 并发上限

动作immediate 档并发上限
prefetch50
prerender10

关键约束

约束说明
仅 ChromiumMDN 标注 Experimental、非 Baseline;Firefox/Safari 未默认支持
特性检测HTMLScriptElement.supports('speculationrules')
回退方案<link rel="prefetch">(更老的语法)
CSP内联规则需 script-src 'inline-speculation-rules'
跨站 prefetchrequires: ['anonymous-client-ip-when-cross-origin'] + referrer_policystrict-origin-when-cross-origin
HTTP 响应头Speculation-Rules: "/path/to/rules.json"(无法改 HTML 时用)

完整示例

html
<!-- 内联规则 -->
<script type="speculationrules">
  {
    "prefetch": [
      {
        "where": { "href_matches": "/*" },
        "eagerness": "eager"
      }
    ],
    "prerender": [
      {
        "where": { "href_matches": "/products/*" },
        "eagerness": "moderate"
      },
      {
        "urls": ["/checkout"],
        "eagerness": "conservative"
      }
    ]
  }
</script>
json
// 外部 JSON(用 Speculation-Rules 头指向)
{
  "prefetch": [
    {
      "urls": ["https://cdn.example.com/next-page"],
      "requires": ["anonymous-client-ip-when-cross-origin"],
      "referrer_policy": "strict-origin-when-cross-origin"
    }
  ]
}
ts
// 特性检测
if (
  "supports" in HTMLScriptElement &&
  HTMLScriptElement.supports("speculationrules")
) {
  // 支持 Speculation Rules
} else {
  // 回退
}

content-visibility 速查

属性作用
content-visibility: auto屏外元素跳过布局与绘制(纯 CSS 渲染懒加载)
content-visibility: visible(默认)正常渲染
content-visibility: hidden类似 display: none 但保留状态
contain-intrinsic-size: <size>屏外时占位的固有尺寸,防滚动条抖动

关键:content-visibility: auto 不阻止子元素(含 <img>)的网络下载——它是渲染层懒加载,与 IO(下载层)互补而非替代。

浏览器支持版本(2026-07)

特性ChromeEdgeFirefoxSafari状态
<img loading="lazy">77+79+75+15.4+Baseline Widely Available
<iframe loading="lazy">77+79+121+16.4+Baseline
Intersection Observer API51+79+55+12.1+Baseline Widely Available
content-visibility: auto85+85+125+17.0+Baseline
Speculation Rules(prefetch)121+121+Experimental · 非 Baseline
Speculation Rules(完整 prerender)121+121+Experimental · 非 Baseline
HTMLScriptElement.supports121+121+Experimental

Speculation Rules:MDN 标注 Experimental、非 Baseline;Firefox/Safari 截至 2026-07 未默认支持。生产用必须特性检测 + 回退。

版本与运行环境

取值
<img loading="lazy"> Baseline2022 年起 Widely Available
Speculation Rules 完整 prerenderChrome 121+(2024-01)
Vue Router 路由懒加载稳定多年,无版本门槛
React.lazy + SuspenseReact 16.6+
webpack 魔法注释 prefetch/preloadwebpack 2.4+ / 4.x 起广泛使用
Vite 等价通过插件或 import.meta.prefetch(实验)实现

官方资源