浏览器之资源获取优先级(fetchpriority)(二)

简介: 浏览器之资源获取优先级(fetchpriority)(二)

Fetch Priority

Fetch Priority API 用于向浏览器指示资源的相对优先级。可以通过向 <img><link><script><iframe> 元素添加 fetchpriority 属性或通过 Fetch API 上的 priority 属性来配置优先级。

浏览器主要根据请求的类型和在文档标记中的位置来确定请求的优先级。

下面是一些示例和相应的代码,以说明不同资源的优先级:

  1. CSS 文件:在文档的 <head> 中请求的 CSS 文件通常被赋予最高优先级
<head>
  <link rel="stylesheet" href="styles.css">
</head>
  1. JavaScript 文件:一般情况下,没有 asyncdefer 属性的 <script> 元素将被视为阻塞渲染资源,并被赋予较高优先级
<script src="script.js"></script>
  1. 图像:图像通常具有较低的默认优先级。我们可以通过添加 fetchpriority 属性来调整图像的优先级。
<img src="image.jpg" fetchpriority="high">
  1. 预加载资源:使用 <link rel="preload"> 元素可以预先加载资源,但它不会直接影响资源的优先级。
<link rel="preload" href="resource.js" as="script">

除了一些特殊的资源,对于其他常规的资源,浏览器按照发现资源的顺序下载具有相同优先级的资源。


fetchpriority

fetchpriority 属性可以用于提示浏览器增加降低所请求资源的优先级。

该枚举属性可以有三个值:

  • high : 该资源相对于其默认优先级更高
  • low : 该资源相对于其默认优先级更低
  • auto : 默认值

Chromium源码中,我们找到对应的定义。

image.png

举例说明

<img src="/789.jpg" alt="前端柒八九" fetchpriority="high" />

在上面的示例中,我们提示浏览器 <img> 的优先级比其默认优先级高。

对于 fetch 方法上的 priority 属性,同样支持相同的值。

fetch("/api/data.json", { priority: 'high' })

在上面的 fetch 请求中,我们向浏览器指示该 fetch 请求的优先级较其默认优先级更高。


Default priority

Fetch Priority API 可以增加降低资源相对于其默认优先级的优先级。

例如,默认情况下,图片始终具有低优先级。将 fetchpriority="high" 分配给图片将把它们的优先级提升为高优先级。

另一方面,渲染阻塞的样式表默认情况下具有最高优先级。将其分配为 fetchpriority="low" 将把其优先级降低为高优先级,而不是低优先级

fetchpriority 用于相对于默认值调整资源的优先级,而不是显式设置其值。

Chromium 的资源优先级文档中记录了 Fetch Priority 对资源优先级的影响,包括不同的资源类型,它们的默认优先级(◉),以及使用 fetchpriority="high"(⬆)和 fetchpriority="low"(⬇)时的结果优先级。

image.png

image.png

  • 使用"as"进行preload或使用"type"进行fetch的操作将使用它们请求的类型的优先级,除非另有说明(比如字体)。
  • 例如,使用"preload as=stylesheet"将使用最高优先级。如果没有指定"as",它们将表现得像XHR(XMLHttpRequest)。
  • "Early"指的是在请求任何非预加载的图像之前进行的请求("late"指的是之后)。
  • 当CSS的媒体类型不匹配时,预加载扫描器不会获取该CSS,而只有当主解析器到达时才会处理它,这通常意味着它将在非常晚的时候被获取,并且具有"late"优先级。

优先级变化

图像始终以低优先级开始。如果在布局过程中发现图像在视口内,则优先级将提升为高优先级,尽管这可能发生在加载过程中的相当晚的阶段。

位于页面底部并阻塞的脚本中等优先级。但是,如果主HTML解析器到达并被阻塞,优先级将提升为高优先级。(前面我们讲过,js解析器阻断资源)

网络堆栈优先级名称

顺便说一嘴,在ChromeNetworkDevTool中也会显示资源优先级。

Chrome网络堆栈中显示的资源优先级名称与Chromium中的Blink中有些不同。但是,它们在自己的规则范围中,是能正确表达各个资源之间的优先级关系的。

完整的映射如下:

Chrome网络堆栈优先级名称 Chrome优先级名称
IDLE Lowest
LOWEST Low
LOW Medium
MEDIUM High
HIGHEST Highest


紧凑模式(Tight mode)

在前面的前置知识中我们已经讲过何为{紧凑模式|Tight mode},并且还将其与{空闲模式|Idle mode}进行了对比。这里就不在赘述了。

image.png

在上面的瀑布图中,您可以看到资源 image-1.jpg 直到 style-2.css 完成下载后才开始下载,即使它已经被解析器探知。此时,只剩下一个正在处理的资源 - script.js,所以浏览器开始下载低优先级的图片。

一旦所有位于 <head> 中的阻塞脚本被下载并执行完成(带有 asyncdefer 的脚本不会阻塞渲染),初始阶段就完成了。即使有超过两个同时进行的请求,浏览器现在可以根据资源的优先级和在标记中的顺序继续下载任何剩余的资源

image.png

在上面的图表中,一旦渲染阻塞的 JavaScript下载并执行(粉色条),浏览器开始下载图片,即使两个 CSS 文件仍在进行中。黄色的垂直条表示 DOM 可交互(即 readystatechange 事件被触发)的时间点。


案例分析

preconnet

如果图片位于不同的域名上,浏览器在下载文件之前需要打开到该域名的连接。

image.png

这在 WebPageTest 的图表中显示为绿色橙色洋红色的条形图,表示在下载之前的预连接过程。

我们可以使用 preconnect 资源提示来提前开始下载图片。

image.png

在上面的图表中,在初始阶段之前,浏览器打开了与 cdn.glitch.global 域的连接,这使得浏览器能够开始下载文件。一旦浏览器退出初始阶段(黄色垂直线),它立即开始下载图片,从而节省了约 350 毫秒的时间。


preload

preload 指令允许你向浏览器提供关于“晚发现”(late-discovered)的关键资源的信息。这对于在样式表或脚本中加载的资源特别有用,例如背景图片字体

在我们的示例中,图片在标记中声明并且早早被发现,因此 preload 的效果很小。(效果有,但是不多)

image.png

在上面的图表中,我们用以下内容替代了 preconnect

<link
  rel="preload"
  as="image"
  href="https://cdn.glitch.global/.../image-1.jpg"
/>

尽管使用了 preload,但图片仍然要等到同时进行的请求少于两个时才开始下载。

预加载资源类型

这里在额外说一些,关于哪些资源可以使用prelaod

image.png


fetchpriority

既然perlaod在有些场景中效果不是很好,那么我们可以另谋出路。

我们可以使用 Fetch Priority 来向浏览器指示 image-1.jpg 的优先级比默认优先级更高,使用以下方式:

<img
  src="https://cdn.glitch.global/.../image-1.jpg"
  fetchpriority="high"
  alt=""
/>

这将把图片的初始优先级从低优先级提升到高优先级,使得图片可以在初始阶段被加载

image.png

上面的瀑布图显示了在初始阶段与其他关键资源并行加载image-1.jpg。这给我们带来了迄今为止最大的改进。


将 preload 和 fetchpriority 合并

到目前为止,Fetch Priority 只在基于 Chromium 的浏览器上受支持,然而,它在不支持识别 fetchpriority 属性的浏览器上会有优雅的失败处理。这使得我们可以将 preload 指令与 Fetch Priority 结合使用。

image.png

<link
  rel="preload"
  as="image"
  fetchpriority="high"
  href="https://cdn.glitch.global/.../image-1.jpg"
/>

支持 Fetch Priority 的浏览器将使用分配的 fetchpriority 进行预加载资源,而不支持的浏览器将使用 preload 指令进行预加载。

上面的图表显示了与之前包含在 <img> 元素上的 fetchpriority 属性的图表类似的结果。这种方法的优点在于统一了在支持 Fetch Priority 和不支持的浏览器上优先处理资源的方法。


fetchpriority 的好处

image.png

fetchpriority 的好处是指资源被发现的时间与开始下载的时间之间的差异。我将其称为机会。因此,如果资源早早被发现,但浏览器开始下载它的时间较晚,那么机会就更大。

如果图像来自不同的域名,还可以将将建立连接的时间包括在机会中。


总结

由于篇幅有限,关于LCP的内容,这里先不展开,我们会单独出一篇文章。

  • 将 LCP 图像托管在与 HTML 文档相同的域上。如果无法实现,请使用 preconnect 提前打开连接。
  • LCP 图像应包含在文档标记中。如果无法实现,请使用 preload 告知浏览器在请求前下载图像。
  • 尽量避免阻塞资源。如果 LCP 图像以低优先级下载,可以使用 fetchpriority 提示浏览器提前下载图像。

后记

分享是一种态度

参考资料:

  1. PerformanceNavigationTiming
  2. Resource timing
  3. Chrome Resource Priorities and Scheduling
  4. WebPageTest

全文完,既然看到这里了,如果觉得不错,随手点个赞和“在看”吧。

相关实践学习
Serverless极速搭建Hexo博客
本场景介绍如何使用阿里云函数计算服务命令行工具快速搭建一个Hexo博客。
相关文章
Request请求转发和重定向的资源路径问题,目录到底加不加,取决于浏览器用,还是服务器用,规避项目目录发生修改,导致重定向失败
Request请求转发和重定向的资源路径问题,目录到底加不加,取决于浏览器用,还是服务器用,规避项目目录发生修改,导致重定向失败
|
11月前
|
Web App开发 前端开发 JavaScript
浏览器之资源获取优先级(fetchpriority)(一)
浏览器之资源获取优先级(fetchpriority)(一)
124 0
|
机器学习/深度学习 移动开发 JavaScript
「沙里淘金」精选浏览器端JavaScript库资源推荐(下)
「沙里淘金」精选浏览器端JavaScript库资源推荐
|
存储 移动开发 JSON
「沙里淘金」精选浏览器端JavaScript库资源推荐(上)
「沙里淘金」精选浏览器端JavaScript库资源推荐
|
JavaScript 安全 前端开发
浏览器原理 31 # 同源策略:为什么XMLHttpRequest不能跨域请求资源?
浏览器原理 31 # 同源策略:为什么XMLHttpRequest不能跨域请求资源?
121 0
浏览器原理 31 # 同源策略:为什么XMLHttpRequest不能跨域请求资源?
|
XML 安全 数据格式
网页 视频作为背景(解决google浏览器无法访问本地资源的问题)
网页 视频作为背景(解决google浏览器无法访问本地资源的问题)
172 0
网页 视频作为背景(解决google浏览器无法访问本地资源的问题)
案例分享:Qt九宫格图片资源浏览器(支持window、linux、兼容各国产系统,支持子文件夹,多选,全选,图片预览,行数与列数设置等)
案例分享:Qt九宫格图片资源浏览器(支持window、linux、兼容各国产系统,支持子文件夹,多选,全选,图片预览,行数与列数设置等)
案例分享:Qt九宫格图片资源浏览器(支持window、linux、兼容各国产系统,支持子文件夹,多选,全选,图片预览,行数与列数设置等)
|
存储 域名解析 缓存
浏览器内核之资源加载与网络栈(下)
此文章是我最近在看的【WebKit 技术内幕】一书的一些理解和做的笔记。 而【WebKit 技术内幕】是基于 WebKit 的 Chromium 项目的讲解。 书接上文 浏览器内核之WebKit 架构与模块
181 0
浏览器内核之资源加载与网络栈(下)
|
缓存 前端开发 JavaScript
浏览器内核之资源加载与网络栈(上)
此文章是我最近在看的【WebKit 技术内幕】一书的一些理解和做的笔记。 而【WebKit 技术内幕】是基于 WebKit 的 Chromium 项目的讲解。 书接上文 浏览器内核之WebKit 架构与模块
290 0
浏览器内核之资源加载与网络栈(上)
|
21天前
|
JSON 移动开发 JavaScript
在浏览器执行js脚本的两种方式
【10月更文挑战第20天】本文介绍了在浏览器中执行HTTP请求的两种方式:`fetch`和`XMLHttpRequest`。`fetch`支持GET和POST请求,返回Promise对象,可以方便地处理异步操作。`XMLHttpRequest`则通过回调函数处理请求结果,适用于需要兼容旧浏览器的场景。文中还提供了具体的代码示例。
在浏览器执行js脚本的两种方式

热门文章

最新文章

下一篇
无影云桌面