应精准使用 preload 加载首屏必需资源(如 hero 图片、字体),避免滥用导致重复请求;内联关键 CSS 并控制在 14KB 内;首屏图片必须显式设置 loading="eager";禁用 head 中同步脚本,改用 defer 或 module。

用 preload 提前加载关键资源,但别乱用
首屏渲染卡顿,往往不是 JS 太大,而是浏览器不知道哪些资源该优先下载。preload 能让浏览器在解析 HTML 时就发起关键资源请求,比如首屏用到的字体、核心 CSS 或 hero 图片。
常见错误是把所有 <link rel="stylesheet"> 都换成 preload——这反而会阻塞渲染,因为 preload 不带执行语义,CSS 还得靠后续 <link rel="stylesheet"> 来应用,结果下了一次又下一次。
- 只对真正首屏必需的资源用
preload:比如<link rel="preload" href="hero.webp" as="image">或<link rel="preload" href="fonts.woff2" as="font" type="font/woff2" crossorigin> -
as属性必须写准,否则浏览器无法正确设置请求优先级或缓存策略(如as="script"和as="fetch"的优先级不同) - 不要对内联
<style>或已内联的 JS 做preload,没意义
内联关键 CSS,但要控制体积和更新成本
外部 CSS 文件会触发“渲染阻塞”,哪怕只有 1KB,浏览器也得等它下载解析完才画首屏。把首屏必需的样式(如 header、hero 区块、按钮基础样式)内联进 <head>,能跳过一次 HTTP 请求。
问题在于:手写内联容易漏改、难维护;全自动提取又可能把非首屏样式也塞进来,白占 HTML 体积。
立即学习“前端免费学习笔记(深入)”;
- 用工具(如
critters或mini-css-extract-plugin+critical)生成真正的“首屏 CSS”,别靠肉眼猜 - 内联 CSS 总体积建议压在 14KB 以内(HTTP/1.1 下避免分包,也利于 gzip 压缩率)
- 如果 CSS 依赖动态主题色或用户偏好,内联部分需服务端渲染时注入,不能全靠 JS 后置补
用 loading="eager" 确保首屏图片不被懒加载拦截
现代浏览器默认对 <img> 启用懒加载(loading="lazy"),但这是双刃剑:首屏图片若没显式声明 loading="eager",可能因滚动检测逻辑误判而延迟加载,造成视觉空白。
尤其在 SSR 或静态站点中,HTML 已含首屏 <img src="...">,但没设 loading 属性,就默认懒加载——这是最隐蔽的首屏卡点之一。
- 所有明确属于首屏视口内的
<img>和<iframe>必须加loading="eager" - 不要依赖 JS 动态加属性(如 onload 后 setAttribute),此时图片早已触发懒加载逻辑
-
<picture>里每个<source>不需要单独设loading,只在<img>上设即可
避免在 <head> 里写同步脚本或复杂内联逻辑
很多人为了“快一点”,把初始化逻辑直接写在 <head> 的 <script> 里,结果反而拖慢首屏:同步脚本会暂停 HTML 解析,还可能触发样式计算或 layout,让浏览器更晚输出首帧。
典型翻车场景:在 <head> 里用 document.write 插广告、用 getComputedStyle 读取元素尺寸、或调用未定义的全局函数。
- 所有非必要 JS 全部移出
<head>,放到<body>底部或用defer属性 - 真需要 head 里运行的代码(如 UA 检测、CDN 切换),确保无 DOM 读写、无样式查询、不依赖尚未解析的资源
- 用
<script type="module">替代传统<script>,天然支持defer且更易做 tree-shaking
loading="lazy" 默认值、没声明 as 的 preload、以及藏在 <head> 里三行看似简单的 JS —— 它们不会报错,但会让 LCP 多拖 300ms。



















