其他
当 FCP/LCP/FID 受关键资源加载顺序影响时…
用于 Web 页面加载性能优化:通过调整关键资源的发现、下载与执行顺序来改善 FCP、LCP 和 FID。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 49/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 85/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 59/100 ×0.15
适用场景
当 FCP/LCP/FID 受关键资源加通用
解决思路
- 内联关键 CSS 和字体 CSS;对外部字体使用 preconnect。
- 按 FCP → LCP → FID 的顺序排列资源,使 FCP 所需资源优先于 LCP 所需资源,LCP 所需资源优先于 FID 所需资源。
- 在网络上先于 ATF 图片开始获取 1P JS。
- 对非关键脚本使用 `async` 或 `defer` 属性。
- 懒加载首屏以下(BTF)图片和非必要第三方资源。
- 确保 FCP 触发时 hero image 已可用来触发 LCP。
- 确保 LCP 触发时 JS 已下载、解析并准备执行(或正在执行)以解除 FID。
- 管道化资源以充分利用 CPU 和网络,避免网络受限时 CPU 空闲、CPU 受限时网络空闲。
- 在适合时让脚本顺序下载,使第一个脚本下载完即可开始 CPU 处理,以提高 CPU 和网络利用率。
- 将 3P 资源纳入整体加载序列并加以控制,不要随意添加。
- 了解浏览器平台怪癖,因为不同浏览器对请求优先级和 hint 的实现不同。
- 仅在确定资源会在当前页使用时使用 `<link rel=preload>`。
- 注意 Chromium 的 preload bug:通过 `<link rel=preload>` 发出的请求可能先于 preload scanner 看到的更高优先级请求。
- 不要依赖 HTTP/2 优先级来精确控制资源顺序,因为服务器或 CDN 可能重新排序、部分实现、错误实现或不实现优先级。
- 进行资源级优化:内联关键 CSS、正确设置图片尺寸、对 JS 做 code-split 并增量交付。
- code-split 时平衡粒度:较高粒度可减少单个路由和后续交互所需 JS,并允许缓存公共依赖;过细会降低单个 chunk 压缩率并影响浏览器性能。
- 消除死代码和未使用代码,避免不必要的 JS 被发送到浏览器。
- 不要向现代浏览器发送 ES5 转译代码和 polyfills。
- 推动库和 npm 包发布 ES module 格式,以便 bundler 做 tree-shaking 和优化。
- 将 FCP 所需最小 CSS 内联到 HTML,而不是从另一个 CSS 文件导入。
- 只下载当前路由需要的 CSS,并按路由拆分关键 CSS。
- 无法内联关键 CSS 时,preload 它并从与文档同源的源提供。
- 避免从多个域提供关键 CSS,避免直接使用第三方关键 CSS(如 Google Fonts)。
- 用自己的服务器代理第三方关键 CSS。
- 让非内联 CSS 在网络优先级和顺序上高于 1P JS 与 ATF 图片。
- 避免过多内联 CSS 导致 HTML 膨胀和主线程样式解析时间过长;识别关键 CSS 并做 code-splitting。
- 注意内联 CSS 不能被缓存;可通过复制一份可缓存 CSS 请求作为 workaround,但可能引起多次整页布局并影响 FID。
- 内联关键字体 CSS。
- 无法内联字体 CSS 时,用 `preconnect` 加载字体。
- 对所有来自其他源的资源使用 preconnect,提前建立连接。
- 用 preconnect 提前连接 Google Fonts 或其他域字体,避免字体获取延迟影响 FCP。
- 可用 font fallback 解锁 FCP 并让文本可用,但要注意字体跳动影响 CLS,以及真实字体到达时主线程大样式和布局任务影响 FID。
- 为所有 ATF 图片设置尺寸;未设置尺寸会导致布局偏移并影响 CLS。
- 由服务器渲染 ATF 图片占位符。
- 优先处理 hero image,避免延迟 hero image 或空白占位符导致 LCP 过晚。
- 让 hero image 占位符尺寸匹配真实 hero 的固有尺寸;否则 LCP 会重新触发,除非图片叠加替换。
- 注意实际中图片可能触发 FCP,尽管理想上 ATF 图片不应影响 FCP。
- 对 BTF 图片使用懒加载,避免它们与 1P JS 或重要 3P 资源竞争;BTF 图片早于 1P JS 或重要 3P 加载会延迟 FID。
- 让 1P JS 在网络上下载早于 ATF 图片,在主线程上执行早于 3P JS,以提高交互就绪。
- 在 SSR 页面中,1P JS 不阻塞 FCP 和 LCP,但仍需按上述方式排序以保障 FID。
- 避免在 HTML head 中放置同步 3P 脚本,因为它会阻塞 CSS 和字体解析、阻塞 FCP,并阻塞 HTML body 解析。
- 控制 3P 脚本执行,避免其主线程执行延迟 1P 脚本、推迟 hydration 和 FID。
- 若使用 Next.js,使用 ScriptLoader 组件及其 Loading Priorities 调度 3P 脚本。
- 使用 `After-Interactive`:在下次 hydration 后加载 3P 脚本,适合 Tag-managers、Ads、Analytics 等希望尽早但晚于 1P 的脚本。
- 使用 `Before-Interactive`:在 hydration 前加载 3P 脚本,适合 polyfill.io、bot detection、security/authentication、用户同意管理(GDPR)等需先于 1P 执行的脚本。
- 使用 `Lazy-Onload`:让所有其他资源优先于指定 3P 脚本并懒加载,适合 Google Feedback 等 CRM 组件、社交分享按钮、评论等脚本。
- 对 FCP blocking 3P resources 使用 preconnect。
- 对 LCP 所需的 3P personalized ATF image 使用 preconnect。
- 对首次用户交互前必须执行的 3P 使用 preconnect。
- 对 Default 3P JS 使用 preconnect。
- 利用 Chrome 资源优先级表:CSS 和 Fonts 以最高优先级加载,因此优先关键 CSS 和字体。
- 利用脚本优先级规则:文档中位置和 `async`/`defer`/blocking 影响脚本优先级。
- 利用脚本优先级规则:第一个图片前的 blocking scripts 高于第一个图片后的 blocking scripts。
- 利用脚本优先级规则:`async`/`defer`/injected scripts 最低。
- 用合适的 `async` 和 `defer` 属性优先化不同脚本。
- 利用图片优先级规则:视口内可见图片优先级高于视口外图片,以此优先 ATF 图片而非 BTF 图片。
- 尽量避免使用 preload,因为它要求手动 preload 每个前置资源并手动维护顺序。
- 尤其避免对字体使用 preload,因为关键字体难以检测。
- 在用户交互开始前获取非关键 CSS,避免后续渲染导致样式问题。
- 在网络上先开始获取 1P JS,再获取 ATF 图片,因为 JS 下载和解析需要时间。
- 允许 HTML 主线程解析和 ATF 图片下载与 1P JS 解析并行进行。
- 无 3P 时,按网络请求顺序执行:1 小段内联 1P 脚本;2 内联关键 CSS(若外部则 preload);3 内联关键字体 CSS(若外部则 preconnect);4 LCP 图片(若外部则 preconnect);5 字体(由内联 font-css 触发,preconnect);6 非关键 async CSS;7 用于交互的 1P JS;8 ATF 图片(preconnect);9 BTF 图片;10 懒加载 JS chunks。
- 无 3P 时,按主线程事件顺序执行:解析 HTML;执行小段内联 1P 脚本;解析 FCP 资源(关键 CSS、字体);触发 FCP;渲染 LCP 资源(hero image、文本);触发 LCP;渲染重要 ATF 图片;视觉完成;解析非关键 async CSS;执行 1P JS 并 hydrate;触发 FID。
- 有 3P 时,按网络请求顺序执行:FCP blocking 3P resources;小段内联 1P 脚本;内联关键 CSS(若外部则 preload);内联关键字体 CSS(若外部则 preconnect);LCP 所需的 3P personalized ATF image;LCP 图片(若外部则 preconnect);字体(由内联 font-css 触发,preconnect);非关键 async CSS;首次用户交互前必须执行的 3P;用于交互的 1P JS;默认 3P JS;BTF 图片;懒加载 JS chunks;较不重要的 3P JS。
- 有 3P 时,按主线程事件顺序执行:解析 HTML;执行小段内联 1P 脚本;解析 FCP blocking 3P resources;解析 FCP 资源(关键 CSS、字体);触发 FCP;渲染 LCP 所需的 3P personalized ATF image;渲染 LCP 资源(hero image、文本);触发 LCP;渲染重要 ATF 图片;解析非关键 async CSS;执行首次用户交互前必须执行的 3P;执行 1P JS 并 hydrate;触发 FID。
- 结合 preconnect、script 属性(async/defer)和 Next.js ScriptLoader 来获得所有脚本的期望加载顺序。
适用边界 · 注意事项
- 无法控制页面 HTML、资源加载顺序或脚本插入方式时,这些重排手段无法落地。
- 页面没有首屏渲染或用户交互目标(例如纯 API、后台任务)时,不需要按 FCP/LCP/FID 序列优化。
- 不要过度内联 CSS/字体或滥用 preload;当内联导致 HTML 膨胀、主线程解析过久,或资源当前页未必使用时,应避免。