资源优先级与 Priority Hints:让关键资源更快加载的实战指南
很多性能优化建议会说:
- “把图片压小一点”
- “把 JS 拆包”
- “减少请求数”
这些都对,但它们解决的是“总量”。
而用户体验往往取决于“关键路径”:
- 首屏主内容(LCP)需要的图片/字体/CSS
- 首次交互前必须执行的 JS
如果关键资源没有优先级,浏览器就可能把带宽浪费在非关键资源上:
- 首屏主图还没到,统计脚本先到了
- 标题字体还没到,下面的非首屏图片先到了
本文讲清楚两个问题:
- 浏览器如何决定资源优先级
- 我们如何用 Priority Hints 与预加载手段让关键资源更快
1. 浏览器的资源优先级:本质是“带宽与主线程调度”
浏览器会根据资源类型与上下文设置默认优先级:
- HTML 文档通常最高
- CSS 会阻塞渲染,优先级高
- JS 会阻塞执行/可能阻塞渲染,通常也高
- 图片的优先级取决于是否在首屏、是否可能成为 LCP
你要做的不是“让一切都高优先级”,而是:
让 LCP 相关资源更早开始下载,并避免被非关键资源抢占。
2. Priority Hints:fetchpriority 的正确用法
Priority Hints 的核心是 fetchpriority 属性(浏览器支持逐步完善)。
常见用法:
- 对 LCP 关键图片:
fetchpriority="high" - 对非关键图片:
fetchpriority="low"
示例:
<img
src="/hero.jpg"
width="1200"
height="630"
fetchpriority="high"
decoding="async"
alt="..."
/>
注意:
- 它不是“强制”,而是“提示”
- 你仍然需要合理的尺寸占位(否则 CLS 会变差)
3. preload / modulepreload:让关键资源更早开始下载
3.1 preload:提前声明“我马上要用”
适合:
- 首屏主图
- 关键字体
- 关键 CSS
示意:
<link rel="preload" href="/fonts/brand.woff2" as="font" type="font/woff2" crossorigin>
3.2 modulepreload:现代 JS 的依赖预加载
对 ESM 依赖可以用 modulepreload 提前加载。
这在“首屏必须执行的模块”上会更有效。
4. preconnect / dns-prefetch:把连接成本提前
当你的关键资源来自第三方域名时(例如:CDN、字体、API),连接建立成本可能很高。
4.1 preconnect
<link rel="preconnect" href="https://cdn.example.com" crossorigin>
它会提前做 DNS/TCP/TLS,减少关键资源开始下载的延迟。
4.2 dns-prefetch
<link rel="dns-prefetch" href="//cdn.example.com">
它更轻量,但效果也更有限。
5. Nuxt/Vite 项目里的落地思路
5.1 先识别你的 LCP 元素
优化优先级的第一步:确定 LCP 是谁。
- 通常是首屏主图
- 或首屏大标题区域
然后围绕它做:
- 图片:
fetchpriority=high+ 预加载(必要时) - CSS:避免关键 CSS 迟到
- 字体:减少字重 +
font-display: swap+ 关键字体 preload
5.2 预加载不是越多越好
常见踩坑:
- preload 一堆资源,反而抢带宽
- preload 了用不到的资源,浪费
经验法则:
- preload 只给“首屏必需、且很可能成为瓶颈”的资源
6. 可复制的检查清单(上线前 10 分钟)
- LCP 元素已确认(DevTools / Lighthouse)
- LCP 图片具备尺寸或固定比例容器(避免 CLS)
- LCP 图片使用
fetchpriority="high" - 关键字体字重减少,使用
font-display: swap - 只对少量关键资源使用 preload(避免过度)
- 第三方域名关键资源使用 preconnect(谨慎)
结语:优先级优化是“让关键路径更确定”
当你把关键资源的下载时机、连接成本与带宽抢占控制住,很多 LCP 的提升会比“继续压缩 5KB 图片”更明显。
下一步建议结合 INP,把“长任务拆分与调度策略”也落地,这样 LCP 与 INP 两条关键路径都能被系统化治理。


