必须写在最前面,因为浏览器预扫描器仅在html解析初期扫描文本流,遇同步脚本即暂停,后续preload被忽略,导致lcp资源无法提前发现。

为什么里必须写在<script>前面</script>
因为浏览器预扫描器(Preload Scanner)只扫HTML文本流,不执行JS;一旦遇到同步<script>,解析器会暂停HTML构建、下载并执行脚本,预扫描器也就停了——此时后面所有的<link rel="preload">都会被跳过,LCP图片资源根本不会被提前发现。</script>
常见错误现象:<script src="analytics.js"></script>写在<link rel="preload" href="hero.webp" as="image">之前,导致hero.webp按普通<img>优先级加载,LCP延迟300–600ms。
-
<link rel="preload">必须出现在任何同步<script></script>标签之前,最好紧贴<meta charset>之后 - 如果必须用内联脚本(如CSP nonce注入),确保它不包含阻塞逻辑,或改用
defer - SSR/SSG模板中容易把统计脚本硬编码在
顶部,要人工检查顺序
fetchpriority="high"单独用对LCP基本没用
fetchpriority="high"只是调度提示,不是资源发现机制。浏览器得先“看见”这个资源,才轮得到它排队——而“看见”的唯一可靠路径,是让预扫描器在HTML首几百字节里扫到src或href值。
常见错误现象:只给<img fetchpriority="high">加属性,但src为空或为data-src;或者<img>被包裹在<template></template>里,预扫描器直接跳过。
- 必须保证LCP图片的
<img>有真实、可访问的src(非空、非about:blank、路径可访问) -
fetchpriority="high"只在Chrome 107+/Edge 107+生效,Safari和Firefox忽略;不能替代<link rel="preload"> - 同一张图既
preload又写<img src>时,确保href和src完全一致(含大小写、查询参数),否则可能触发重复请求
字体加载位置不当会把LCP从图片拖成文字块
当LCP候选元素是大标题(<h1></h1>)而非图片时,往往是因为图片加载太慢或未被预发现,而系统字体又因@font-face阻塞渲染——此时浏览器被迫等字体下载+解码完才绘制文字,LCP时间反而比图片方案更不可控。
使用场景:CMS模板限制无法改<img>结构,或首屏是大段品牌文案+小图。
- 关键字体文件必须用
<link rel="preload" as="font" type="font/woff2" crossorigin>预加载,且crossorigin不可省 - @font-face规则里必须设
font-display: swap,避免文字渲染被卡住 - 不要把字体
preload写在CSS文件里——它必须出现在HTML的中,早于任何样式表引用
嵌套过深的结构会隐式延长LCP发现窗口
HTML解析器本身不关心嵌套,但大型框架(Next.js/Nuxt)输出的常带多层<div>或自定义标签(如<code><nexthead></nexthead>),这些节点虽不渲染,却增加Token数量和DOM构建耗时——尤其在低端安卓机上,解析延迟100ms,意味着预扫描器启动晚100ms,LCP图片URL被发现的时间就晚100ms。
性能影响:实测内DOM节点超12个、平均嵌套深度>3时,FCP/LCP中位数上升80–150ms(Chrome DevTools → Elements → 右键任意子节点 → Show DOM properties → 查depth)。
- 删掉所有无意义包装容器,比如
<div><title>...</title></div> - 避免在
里用框架组件动态注入meta,改用服务端直出静态标签 - 用
curl -I查响应头Content-Length,若部分超8KB,重点审查冗余节点
<template></template>、不执行JS、不解析CSS,它只认HTML文本流里的src和href。一切绕开这三点的“优化”,都是给LCP指标做表面功夫。**











