预扫描器仅扫描首层HTML字节流,不执行JS、不解析嵌套超6层或惰性容器内的资源,关键资源须直出在初始HTML中且置于语义标签内;fetchpriority和preload必须显式声明于<head>或<body>开头附近,否则信号失效。

预扫描器只认首层 HTML 字节流,不执行 JS
浏览器在开始构建 DOM 之前,会启动一个轻量级的预加载扫描器(Preload Scanner),它不解析 JS、不展开嵌套、不识别条件渲染——只对初始 HTML 字节流做一次快速线性扫描。这意味着:document.createElement('img')、innerHTML、JSX 表达式里生成的 <img> 标签,预扫描器根本看不到。
常见错误现象包括:
- 首屏大图始终是
Medium优先级,LCP 候选元素迟迟不发起请求 -
link rel="preload"声明了字体却仍 FOUC(Flash of Unstyled Content) - Next.js 的
<Image fetchpriority="high">在{isLoaded && <Image>}中完全失效
关键结论:所有需要被提前发现的资源,必须出现在服务端直出的首层 HTML 中,且不能藏在 JS 控制的条件块或深层嵌套里。
DOM 深度超过 6 层,预扫描器直接截断
Chromium 的预扫描器会在 DOM 树深度达到 6 层时主动停止向下读取子节点。这不是性能限制,而是设计决策——它只扫描“可信结构”,连续多层 <div> 嵌套会被当作噪声跳过。
立即学习“前端免费学习笔记(深入)”;
典型失效场景:
-
<picture>内部的<source>能被识别,但整个<picture>若被包在<div class="lazy-load-wrapper">里,且该 wrapper 没有src或loading="eager",预扫描器就当它不存在 -
<details>、<dialog>、<slot>这类惰性容器中的资源,几乎 100% 被忽略 - SSR 输出中用
v-if或*ngIf渲染的关键图片,在初始 HTML 里压根没标签,预扫描器无从响应
建议把关键资源放在语义化标签内(如 <main>、<article>),它们本身会提升子元素资源的探测可信度。
将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
fetchpriority 和 preload 必须在首层显式声明
fetchpriority 不是运行时 API,它只在 HTML 解析阶段被读取一次;link rel="preload" 也必须出现在 <head> 或 <body> 开头附近,才能被及时拾取。一旦被包裹进组件模板、JSX 表达式或条件注释中,信号就彻底失效。
注意兼容性差异:
-
fetchpriority="high"只对<img>和<iframe>生效,且仅 Chromium 119+ 支持 - Safari 17.2+ 仅部分识别
<img>的fetchpriority,Firefox 完全忽略 -
link rel="preload"必须带as属性(如as="style"、as="font"),否则浏览器无法判断资源类型,降级为普通<link>
别在 <style> 块里用 @import 加载 CSS——预扫描器不解析 CSS 内容,@import 是 CSSOM 阶段才触发的串行阻塞行为。
<meta charset> 必须在前 1024 字节内,且位置靠前
浏览器解析 HTML 时,会先用默认编码(通常是 UTF-8)扫描前 1024 字节寻找 <meta charset>。如果没找到,就会按默认编码继续解析;后续即使出现 <meta charset="UTF-8">,也无法修正已错解的字节。
真实踩坑点:
-
<meta charset="UTF-8">放在<title>后面,而<title>内容含中文,可能导致标题乱码 - 文件开头存在 BOM(
EF BB BF)或注释,挤占了有效扫描空间 - 服务器返回的 HTTP
Content-Type头未声明charset=utf-8,进一步增加解析不确定性
最稳妥写法是把 <meta charset="UTF-8"> 放在 <head> 的第一行,确保它落在前 512 字节内——这是多数浏览器实际生效的安全阈值。


















