其他
关键字体、首屏图片或关键脚本在加载瀑布图中发现太晚时,用…
当关键资源(字体、首屏图片、关键脚本)在页面加载后期才被发现时,通过 preload 提前获取以提升加载指标。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 49/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 85/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 60/100 ×0.15
适用场景
关键字体、首屏图片或关键脚本在加载瀑布图通用
解决思路
- 对当前页面立即需要的资源使用 `<link rel="preload">`。
- 使用 `as` 属性指定资源类型,如 `as="script"`、`as="style"`、`as="font"`、`as="image"`。
- 对字体以及其他以 CORS 方式获取的资源,在 preload 上设置 `crossorigin`,使其与最终请求模式一致。
- 只预加载初始渲染后约 1 秒内必须可见的资源。
- 控制预加载数量,避免因预加载过多资源而延迟 First Contentful Paint。
- 优化 Time To Interactive (TTI) 或 First Input Delay (FID) 时,可用 preload 加载交互所需的 JavaScript bundle 或 chunk。
- 使用 preload 加载交互脚本时,注意不要以延迟 hero image、字体等 First Contentful Paint (FCP) 或 Largest Contentful Paint (LCP) 必需资源为代价。
- 若优化第一方 JavaScript 的加载,可考虑把 `<script defer>` 放在 document `<head>` 而不是 `<body>`,帮助浏览器更早发现这些资源。
- 在单页应用中区分:prefetch 用于缓存可能很快请求的资源,preload 用于需要立即使用的资源(如初始渲染使用的字体或用户马上看到的图片)。
- 记住 preload 不像 prefetch 由浏览器根据网络和带宽决定,preload 资源会无条件预加载。
- 若某组件(如 `EmojiPicker`)应在初始渲染立即可见、不应放入 main bundle,但应与主 bundle 并行加载,可在动态 import 中加入 Webpack 魔法注释:`const EmojiPicker = import(/* webpackPreload: true */ "./EmojiPicker");`。
- Webpack 4.6.0+ 可直接使用 `/* webpackPreload: true */`;旧版 Webpack 需在 webpack config 中添加 `preload-webpack-plugin`。
- 构建应用后检查 Webpack 输出,确认生成了对应 preload link,例如 `<link rel="preload" href="emoji-picker.bundle.js" as="script" />` 和 `<link rel="preload" href="vendors~emoji-picker.bundle.js" as="script" />`。
- 若要让浏览器以高优先级下载脚本但不让 parser 阻塞等待脚本,可使用 preload + async hack:写 `<link rel="preload" href="emoji-picker.js" as="script">`,并使用 `<script src="emoji-picker.js" async>`。
- 使用 preload + async hack 时接受权衡:该 preload 可能延迟其他资源的下载。
- 预加载字体时必须使用 `crossorigin`。字体即使自托管在同源,也会按 CORS 资源获取;preload 请求和最终 `@font-face` 请求必须使用相同 fetch mode,否则 preload 无法复用。
- 字体 preload 应写成类似:`<link rel="preload" href="/fonts/inter-roman.woff2" as="font" type="font/woff2" crossorigin>`,避免遗漏 `crossorigin` 导致先 `no-cors` 预加载、后 `cors` 再次获取同一文件。
- 确保 `@font-face` 指向同一资源,例如:`@font-face { font-family: "Inter"; src: url("/fonts/inter-roman.woff2") format("woff2"); font-display: swap; }`。
- 更广泛地,若最终消费者以 CORS 语义获取某资源,preload 也应匹配该模式。
- 在 Chrome 95+ 中,把 preload 放在 HTTP headers 会跳到最前。
- 在 Chrome 95+ 中,对于优先级 >= Medium 的资源,preload 通常会按 parser 遇到它们的顺序加载,因此小心把 preload 放在 HTML 开头。
- 字体 preload 最好放在 `head` 末尾或 `body` 开头。
- import preload 应放在需要该 import 的 script tag 之后,以便实际脚本先被加载/解析。
- image preload 优先级较低,应相对于 async scripts 和其他 low/lowest priority tags 来排序。
- 谨慎少量使用 preload,并在生产环境测量其影响。
- 若图片 preload 在文档中比图片本身更早出现,可帮助浏览器发现该图片,并相对其他资源排序。
- 注意 preload 使用不当会让图片等资源延迟 FCP(例如 CSS、字体),与目标相反。
- 为了让重新调整优先级有效,依赖服务器正确地对请求进行优先级排序。
- `<link rel="preload">` 还可用于获取脚本但不执行它们。
- 查阅并应用 web.dev 指南:preload 交互所需关键脚本、preload LCP 图片、在防止布局偏移的情况下加载字体。
适用边界 · 注意事项
- 非关键资源不要用 preload;预加载太多会延迟真正影响首次渲染的资源。
- 浏览器预加载扫描器已经能提前发现的资源不要用 preload(例如 `<head>` 中的 inline `<script>` 标签)。
- 过度使用导致浏览器对未使用的预加载资源发出警告时,说明浪费带宽,应停止或减少 preload。