预扫描器仅扫描HTML前6层DOM深度且不解析JS或条件逻辑,导致深层嵌套、JS挂载、<noscript>内、data-src及错误preload等资源无法被识别。

预扫描器根本看不到深层嵌套里的资源
Chromium 的预扫描器只扫描 HTML 字节流的前 6 层 DOM 深度,超出即截断。它不递归、不解析 JS、不展开 <template> 或 <slot>,更不会执行条件逻辑。
常见失效现象包括:首屏大图始终是 Medium 优先级、LCP 候选元素请求延迟、link rel="preload" 声明了字体却仍 FOUC。
-
<picture>被包在六层<div class="lazy-wrapper">里 → 预扫描器跳过整个节点 -
<img>写在<details>或<dialog>内部 → 标签名都未被读到 - SSR 输出中关键图片由 JS hydration 后挂载 → 初始字节流里根本没有该标签
link rel="preload" 放错位置或写错 as 就等于没写
link rel="preload" 必须出现在 <head> 或 <body> 开头附近,且 href 值要和最终 <img src> 完全一致(大小写、斜杠、查询参数都不能差);as 属性不是装饰,而是调度依据。
写错 as 的后果比你想象得更直接:浏览器按错误类型处理资源,可能降级、静默忽略、或无法复用。
立即学习“前端免费学习笔记(深入)”;
-
as="script"写成as="fetch"→ 请求走低优先级通道,后续<script src>无法复用,重复下载 -
as="font"却漏掉crossorigin→ 浏览器静默丢弃,FOIT 照旧 -
as="style"用于预加载 JS 文件 → 样式解析器拒绝处理,资源进不了样式表缓存 -
<link rel="preload" href="/hero.webp" as="image">若实际<img src="/HERO.WEBP">→ 路径不匹配,preload 失效
fetchpriority="high" 不是万能钥匙,且支持度极有限
fetchpriority="high" 是 Chromium 101+ 引入的调度提示,仅对 <img> 和 <iframe> 生效,Safari 17.2+ 仅部分识别 <img>,Firefox 完全忽略。它不能替代 link rel="preload",也不能修复结构问题。
最常被误用的场景,是把它当成“强制提前加载”的开关,而忽略了它依赖预扫描器先看到该标签这一前提。
- 把
<img fetchpriority="high">放在{isLoaded && <img ...>}条件块里 → SSR 输出无此标签,预扫描器根本看不见 - 用
<div style="background-image: url(...)">承载 LCP →fetchpriority对 CSS 背景图无效 - 同时设
loading="lazy"和fetchpriority="high"→ Chrome 115+ 中 lazy 行为会被降级,但 Safari/Firefox 仍按 lazy 处理
JS 动态插入、data-src、<noscript> 全部绕过预扫描器
预扫描器只看初始 HTML 字节流,不执行 JS,不解析 CSS,也不进入 <noscript> 或 <script type="application/json"> 内容。任何依赖运行时逻辑的资源声明,对它来说都不存在。
这意味着,哪怕你用 IntersectionObserver 精准控制加载时机,只要图片不在初始 HTML 里,就错过了预扫描器发现它的唯一窗口。
-
<img />→ 预扫描器只看到空src或缺失src,不触发请求 -
document.createElement('img').src = '/hero.jpg'→ JS 执行阶段才插入,晚于预扫描器工作时间 -
<noscript><img src="/fallback.jpg"></noscript>→ 预扫描器跳过整个<noscript>块 - Vue 的
v-if或 React 的{condition && <img>}→ SSR 输出中无该节点,预扫描器无从识别
src、href 和 as。所有靠 JS、CSS、条件渲染、深度嵌套来“藏资源”的做法,本质上都是在对抗它的设计边界。



















