Fetch Priority API 指示浏览器资源的相对优先级。它可以实现最佳加载并改进 Core Web Vitals。
当浏览器解析网页并开始发现和下载资源(例如图像、脚本或 CSS)时,它会为这些资源分配一个提取 priority
,以便能够以最佳顺序下载它们。资源的优先级通常取决于资源的类型及其在文档中的位置。例如,视口内的图像可能具有 High
优先级,而使用 <head>
中的 <link>
标记的早期加载、渲染阻塞型 CSS 的优先级可能为 Very High
。浏览器在分配效果良好的优先级方面做得相当不错,但在所有情况下可能并非最佳。
本页讨论 Fetch Priority API 和 fetchpriority
HTML 属性,该属性允许您提示资源的相对优先级(high
或 low
)。Fetch Priority 可以帮助优化 Core Web Vitals。
摘要
Fetch Priority 可以提供帮助的几个关键领域
- 通过在图像元素上指定
fetchpriority="high"
来提高 LCP 图像的优先级,从而使 LCP 更早发生。 - 提高
async
脚本的优先级,使用比当前最常见的 hack(为async
脚本插入<link rel="preload">
)更好的语义。 - 降低后期 body 脚本的优先级,以便更好地与图像排序。

从历史上看,开发人员对资源优先级的控制有限,只能使用 preload 和 preconnect。Preload 允许您告知浏览器您希望提前加载的关键资源,在浏览器自然发现它们之前。这对于难以发现的资源尤其有用,例如样式表、背景图像或从脚本加载的资源中包含的字体。Preconnect 有助于预热与跨域服务器的连接,并可以帮助改进诸如 Time to first byte 等指标。当您知道源,但不一定知道将要使用的资源的确切 URL 时,它非常有用。
Fetch Priority 补充了这些 Resource Hints。它是一个基于标记的信号,可通过 fetchpriority
属性获得,开发人员可以使用它来指示特定资源的相对优先级。您还可以通过 JavaScript 和 Fetch API 以及 priority
属性使用这些提示,以影响为数据进行的资源提取的优先级。Fetch Priority 还可以补充 preload。以 Largest Contentful Paint 图像为例,当预加载时,它仍然会获得较低的优先级。如果它被其他早期的低优先级资源推后,则使用 Fetch Priority 可以帮助图像更快地加载。
资源优先级
资源下载顺序取决于浏览器为页面上的每个资源分配的优先级。可能影响优先级计算逻辑的因素包括以下内容
- 资源的类型,例如 CSS、字体、脚本、图像和第三方资源。
- 文档中引用资源的位置或顺序。
- 是否在脚本上使用了
async
或defer
属性。
下表显示了 Chrome 如何确定大多数资源的优先级和顺序
在布局阻止阶段加载 | 在布局阻止阶段一次加载一个 | ||||
---|---|---|---|---|---|
Blink 优先级 |
VeryHigh | High | Medium | Low | VeryLow |
DevTools 优先级 |
最高 | High | Medium | Low | 最低 |
主资源 | |||||
CSS(早期**) | CSS(后期**) | CSS(媒体不匹配***) | |||
脚本(早期**或非来自预加载扫描器) | 脚本(后期**) | 脚本 (async) | |||
字体 | 字体 (rel=preload) | ||||
导入 | |||||
图像(在视口中) | 图像(前 5 张图像 > 10,000 像素2) | 图像 | |||
媒体(视频/音频) | |||||
预取 | |||||
XSL | |||||
XHR(同步) | XHR/fetch*(异步) |
浏览器按照资源被发现的顺序下载具有相同计算优先级的资源。您可以在 Chrome Dev Tools Network 选项卡下检查加载页面时分配给不同资源的优先级。(确保通过右键单击表头并勾选 priority 列来包含该列)。

type = "font"
的资源优先级
type = "script"
的资源优先级。当优先级更改时,您可以在 Big request rows 设置或工具提示中看到初始优先级和最终优先级。

何时可能需要 Fetch Priority?
现在您了解了浏览器的优先级逻辑,您可以调整页面的下载顺序,以优化其性能和 Core Web Vitals。以下是一些您可以更改以影响资源下载优先级的示例
- 按照您希望浏览器下载它们的顺序放置资源标记(例如
<script>
和<link>
)。具有相同优先级的资源通常按照它们被发现的顺序加载。 - 使用
preload
资源提示来更早地下载必要的资源,特别是对于浏览器不容易早期发现的资源。 - 使用
async
或defer
来下载脚本,而不会阻止其他资源。 - 延迟加载折叠下方的的内容,以便浏览器可以将可用带宽用于更关键的折叠上方的资源。
这些技术有助于控制浏览器的优先级计算,从而提高性能和 Core Web Vitals。例如,当预加载关键背景图像时,可以更早地发现它,从而改进 Largest Contentful Paint (LCP)。
有时,这些处理可能不足以针对您的应用程序最佳地确定资源的优先级。以下是一些 Fetch Priority 可能有帮助的场景
- 您有多个折叠上方的图像,但并非所有图像都应具有相同的优先级。例如,在图像轮播中,只有第一个可见图像需要更高的优先级,而其他图像(通常最初在屏幕外)可以设置为具有较低的优先级。
- 视口内的图像通常以
Low
优先级启动。布局完成后,Chrome 会发现它们在视口中并提高它们的优先级。这通常会显着延迟关键图像(如 hero 图像)的加载。在标记中提供 Fetch Priority 可让图像以High
优先级启动并更早开始加载。为了尝试在某种程度上自动化此过程,Chrome 将前五个较大的图像设置为Medium
优先级,这将有所帮助,但显式的fetchpriority="high"
会更好。
对于作为 CSS 背景包含的 LCP 图像的早期发现,仍然需要预加载。要提高背景图像的优先级,请在预加载中包含fetchpriority='high'
。 - 将脚本声明为
async
或defer
会告诉浏览器异步加载它们。但是,如优先级表所示,这些脚本也被分配了“Low”优先级。您可能希望在确保异步下载的同时提高它们的优先级,特别是对于对用户体验至关重要的脚本。 - 如果您使用 JavaScript
fetch()
API 异步提取资源或数据,浏览器会为其分配High
优先级。您可能希望某些提取以较低的优先级运行,特别是如果您将后台 API 调用与响应用户输入的 API 调用混合使用。将后台 API 调用标记为Low
优先级,将交互式 API 调用标记为High
优先级。 - 浏览器为 CSS 和字体分配
High
优先级,但其中一些资源可能比其他资源更重要。您可以使用 Fetch Priority 来降低非关键资源的优先级(请注意,早期 CSS 是渲染阻塞的,因此通常应该是High
优先级)。
fetchpriority
属性
使用 fetchpriority
HTML 属性来指定资源类型(例如 CSS、字体、脚本和图像)在使用 link
、img
或 script
标记下载时的下载优先级。它可以采用以下值
high
:资源具有更高的优先级,并且您希望浏览器将它的优先级设置为高于通常优先级,只要浏览器的自身启发式方法不会阻止这种情况发生。low
:资源具有较低的优先级,并且您希望浏览器降低它的优先级,同样,如果其启发式方法允许这样做。auto
:默认值,允许浏览器选择合适的优先级。
以下是一些在标记中使用 fetchpriority
属性以及脚本等效 priority
属性的示例。
<!-- We don't want a high priority for this above-the-fold image -->
<img src="/images/in_viewport_but_not_important.svg" fetchpriority="low" alt="I'm an unimportant image!">
<!-- We want to initiate an early fetch for a resource, but also deprioritize it -->
<link rel="preload" href="/js/script.js" as="script" fetchpriority="low">
<script>
fetch('https://example.com/', {priority: 'low'})
.then(data => {
// Trigger a low priority fetch
});
</script>
浏览器优先级和 fetchpriority
的影响
您可以将 fetchpriority
属性应用于不同的资源,如下表所示,以提高或降低其计算优先级。每行中的 fetchpriority="auto"
(◉) 标记了该资源类型的默认优先级。(也可作为 Google 文档 获取)。
在布局阻止阶段加载 | 在布局阻止阶段一次加载一个 | ||||
---|---|---|---|---|---|
Blink 优先级 |
VeryHigh | High | Medium | Low | VeryLow |
DevTools 优先级 |
最高 | High | Medium | Low | 最低 |
主资源 | ◉ | ||||
CSS(早期**) | ⬆◉ | ⬇ | |||
CSS(后期**) | ⬆ | ◉ | ⬇ | ||
CSS(媒体不匹配***) | ⬆*** | ◉⬇ | |||
脚本(早期**或非来自预加载扫描器) | ⬆◉ | ⬇ | |||
脚本(后期**) | ⬆ | ◉ | ⬇ | ||
脚本 (async/defer) | ⬆ | ◉⬇ | |||
字体 | ◉ | ||||
字体 (rel=preload) | ⬆◉ | ⬇ | |||
导入 | ◉ | ||||
图像(在视口中 - 布局后) | ⬆◉ | ⬇ | |||
图像(前 5 张图像 > 10,000 像素2) | ⬆ | ◉ | ⬇ | ||
图像 | ⬆ | ◉⬇ | |||
媒体(视频/音频) | ◉ | ||||
XHR(同步)- 已弃用 | ◉ | ||||
XHR/fetch*(异步) | ⬆◉ | ⬇ | |||
预取 | ◉ | ||||
XSL | ◉ |
fetchpriority
设置相对优先级,这意味着它会适当提高或降低默认优先级,而不是显式地将优先级设置为 High
或 Low
。这通常会导致 High
或 Low
优先级,但并非总是如此。例如,具有 fetchpriority="high"
的关键 CSS 保留“Very High”/“Highest”优先级,并且在这些元素上使用 fetchpriority="low"
保留“High”优先级。这两种情况都不涉及显式地将优先级设置为 High
或 Low
。
用例
当您想为浏览器提供关于以什么优先级提取资源的额外提示时,请使用 fetchpriority
属性。
提高 LCP 图像的优先级
您可以指定 fetchpriority="high"
以提高 LCP 或其他关键图像的优先级。
<img src="lcp-image.jpg" fetchpriority="high">
以下比较显示了使用和不使用 Fetch Priority 加载 LCP 背景图像的 Google Flights 页面。通过将优先级设置为 high,LCP 从 2.6 秒提高到 1.9 秒。
降低折叠上方图像的优先级
使用 fetchpriority="low"
来降低不立即重要的折叠上方图像的优先级,例如图像轮播中屏幕外的图像。
<ul class="carousel">
<img src="img/carousel-1.jpg" fetchpriority="high">
<img src="img/carousel-2.jpg" fetchpriority="low">
<img src="img/carousel-3.jpg" fetchpriority="low">
<img src="img/carousel-4.jpg" fetchpriority="low">
</ul>
虽然图像 2-4 将在视口之外,但它们可能被认为“足够接近”以将它们提升到 high
甚至在添加 load=lazy
属性时也加载。因此,fetchpriority="low"
是此问题的正确解决方案。
在早期与 Oodle 应用的实验中,我们使用此方法来降低加载时不显示的图像的优先级。它使页面加载时间减少了 2 秒。

降低预加载资源的优先级
为防止预加载资源与其他关键资源竞争,您可以降低它们的优先级。将此技术与图像、脚本和 CSS 一起使用。
<!-- Lower priority only for non-critical preloaded scripts -->
<link rel="preload" as="script" href="critical-script.js">
<link rel="preload" as="script" href="non-critical-script.js" fetchpriority="low">
<!-- Preload CSS without blocking render, or other resources -->
<link rel="preload" as="style" href="theme.css" fetchpriority="low" onload="this.rel='stylesheet'">
重新确定脚本的优先级
您的页面需要交互的脚本应快速加载,但不应阻止其他更关键的渲染阻塞资源。您可以将这些标记为具有高优先级的 async
。
<script src="async_but_important.js" async fetchpriority="high"></script>
如果脚本依赖于特定的 DOM 状态,则不能将其标记为 async
。但是,如果它们在页面上稍后运行,则可以以较低的优先级加载它们
<script src="blocking_but_unimportant.js" fetchpriority="low"></script>
当解析器到达此脚本时,这仍将阻止解析器,但将允许优先处理此脚本之前的内容。
如果需要完整的 DOM,则另一种选择是使用 defer
属性(在 DOMContentLoaded 之后按顺序运行),甚至在页面底部使用 async
。
降低非关键数据提取的优先级
浏览器以高优先级执行 fetch
。如果您有多个可能同时触发的提取,则可以将高默认优先级用于更重要的数据提取,并降低不太关键的数据的优先级。
// Important validation data (high by default)
let authenticate = await fetch('/user');
// Less important content data (suggested low)
let suggestedContent = await fetch('/content/suggested', {priority: 'low'});
Fetch Priority 实现说明
Fetch Priority 可以在特定用例中提高性能,但在使用 Fetch Priority 时需要注意一些事项
fetchpriority
属性是一个提示,而不是指令。浏览器会尝试尊重开发人员的偏好,但它也可以应用其资源优先级偏好来解决冲突。不要将 Fetch Priority 与预加载混淆
- Preload 是一种强制提取,而不是提示。
- Preload 让浏览器提前发现资源,但它仍然以默认优先级提取资源。相反,Fetch Priority 无助于可发现性,但它确实允许您提高或降低提取优先级。
- 通常,观察和衡量预加载的效果比优先级更改的效果更容易。
Fetch Priority 可以通过提高优先级的粒度来补充预加载。如果您已经将预加载指定为
<head>
中 LCP 图像的第一个项目之一,那么high
Fetch Priority 可能不会显着提高 LCP。但是,如果预加载发生在其他资源加载之后,则high
Fetch Priority 可以更多地提高 LCP。如果关键图像是 CSS 背景图像,请使用fetchpriority = "high"
预加载它。在更多资源争夺可用网络带宽的环境中,优先排序带来的加载时间改进更加相关。这在 HTTP/1.x 连接(其中不可能并行下载)或低带宽 HTTP/2 或 HTTP/3 连接上很常见。在这些情况下,优先级排序可以帮助解决瓶颈。
CDN 并未统一实现 HTTP/2 优先级,HTTP/3 也类似。即使浏览器从 Fetch Priority 传递优先级,CDN 也可能不会按指定的顺序重新确定资源的优先级。这使得测试 Fetch Priority 变得困难。优先级在浏览器内部以及支持优先级的协议(HTTP/2 和 HTTP/3)中均适用。仅为了独立于 CDN 或源支持的内部浏览器优先级,仍然值得使用 Fetch Priority,因为当浏览器请求资源时,优先级通常会发生变化。例如,在浏览器处理关键的
<head>
项时,通常会阻止请求低优先级资源(如图像)。您可能无法在初始设计中将 Fetch Priority 作为最佳实践引入。在开发周期的后期,您可以查看分配给页面上不同资源的优先级,如果它们与您的期望不符,您可以引入 Fetch Priority 以进行进一步优化。
开发者应将 preload 用于其预期用途—预加载解析器未检测到的资源(字体、导入、背景 LCP 图像)。preload
提示的位置会影响资源何时预加载。
Fetch priority 关注的是资源在被提取时应如何提取。
使用预加载的技巧
使用预加载时请记住以下几点
- 在 HTTP 标头中包含预加载会将其置于加载顺序中所有其他内容之前。
- 通常,对于任何具有
Medium
或更高优先级的项,预加载都按照解析器到达它们的顺序加载。如果您在 HTML 的开头包含预加载,请务必小心。 - 字体预加载可能最适合放在 head 的末尾或 body 的开头。
- 导入预加载(动态
import()
或modulepreload
)应在需要导入的 script 标记之后运行,因此请确保先加载或解析 script,以便可以在加载其依赖项时对其进行评估。 - 图像预加载默认具有
Low
或Medium
优先级。相对于异步脚本和其他低优先级或最低优先级标记对其进行排序。
历史记录
Fetch Priority 最早于 2018 年在 Chrome 中作为源试用进行实验,然后在 2021 年再次使用 importance
属性。当时它被称为 Priority Hints。此后,该接口已更改为 HTML 的 fetchpriority
和 JavaScript Fetch API 的 priority
,这是 Web 标准流程的一部分。为了减少混淆,我们现在将此 API 称为 Fetch Priority。
结论
随着预加载行为的修复以及近期对 Core Web Vitals 和 LCP 的关注,开发者可能对 Fetch Priority 感兴趣。他们现在拥有额外的控制旋钮来实现他们首选的加载顺序。