rel
一、认识
rel
属性定义了所链接的资源与当前文档的关系,在 <a>
、<area>
和 <link>
元素上有效。支持的值取决于拥有该属性的元素。
二、语法
三、属性值
3.1 prefetch
资源预读取(Prefetch
) 是一种浏览器优化技术,用于在页面加载过程中 提前请求并缓存未来可能 需要的资源,以减少 后续页面 导航或操作时的延迟。通过使用 Prefetch
,浏览器可以主动去加载和缓存当前页面附加资源(如脚本、样式表、图片等),以便在用户导航到下一个页面时能够更快地获取这些资源。这样可以提高用户体验,因为用户在导航到下一个页面时不需要等待资源的加载,而是能够立即渲染页面。Prefetch
指定用户代理应预先获取并缓存目标资源,因为后续的导航可能需要它。资源预获取 强调的是对后续页面关键资源的提前获取。Prefetch
可以强制浏览器在不阻塞 document
的 onload
事件的情况下请求资源。
在 Chrome
中,如果用户导航离开一个页面,而对其他页面的预取请求仍在进行中,这些请求将不会被终止。
prefetch
加载的是接下来页面可能会使用的资源,因此优先级最低,为Lowest
。
<link rel="prefetch" as="style" href=""/>
<link rel="prefetch" as="script" href=""/>
3.2 preload
资源预加载(preload
) 是一种浏览器优化技术,用于在页面加载过程中提前加载 当前页面 所需的关键资源,以加速页面渲染和提高用户体验。通过使用 preload
,开发者可以指定一些重要资源在页面加载时优先获取,以便在需要时能够立即使用。指定用户代理必须根据 as
属性给出的潜在目的地(以及与相应目的地相关的优先级),为当前导航预先获取和缓存目标资源。资源预加载 强调的是对当前页面关键资源的提前加载。preload
加载的是本页即将要使用的资源, 因此优先级要比 prefetch
高。但具体是多少,要看加载的资源的类型:
<link rel="preload" href="main.js" as="script" />
<link rel="preload" href="myfont.ttf" as="font">
<link rel="preload" href="style.css" as="style" />
<link rel="preload" href="example.png" as="image" />
其中,JS
、CSS
和字体文件preload
的优先级是High
,而image
类型的资源的优先级是Low
,这个和页面中JS
资源的加载不同,对于页面内直连的JS
文件,其加载优先级是Medium
,而IMG
图片则是High
,CSS
是Highest
。
如上所示: 使用as
属性预加载的资源将具有与它们请求的资源类型相同的资源优先级。 例如 preload as =“style”
将获得最高优先级,而 as =“script”
将获得低优先级或中优先级。 这些资源也遵循相同的CSP
策略(例如脚本受 script-src
约束)。不带 as
属性的 preload
的优先级将会等同于异步请求。
3.3 modulepreload
资源预加载 modulepreload
对于原生 ESM
模块,浏览器提供了 modulepreload
来进行预加载:
<link rel="modulepreload" href="main.js" />
3.4 prerender
prerender
指定用户代理应预先获取目标资源,并以有助于在未来提供更快的响应的方式处理它。**预渲染(prerender
)**是一种网页优化技术,它允许浏览器在用户导航到页面之前提前加载并渲染页面内容。这样做可以显著提高页面加载速度和用户体验。
四、扩展
4.1 资源加载优先级
Priority Hints
(优先级提示)是一种用于指导浏览器资源加载顺序的技术。它允许开发者向浏览器提供有关资源加载优先级的建议,以便浏览器更好地决定哪些资源应该优先加载。通过使用 Priority Hints
,开发者可以提高关键资源的加载速度,从而改善页面性能和用户体验。
在 HTML
中,可以使用 <link>
元素的 rel
属性来添加 Priority Hints
。具体来说,以下是一些常用的 Priority Hints
值:
-
preload
: 建议浏览器在页面加载过程中尽早加载该资源。 -
prefetch
: 建议浏览器在后台加载该资源,以备将来使用。 -
prerender
: 建议浏览器预渲染该资源,以提前生成即将展示给用户的页面。
4.2 五层加载优先级
Chrome
浏览器中的5
层优先级指的是网络请求的优先级,这些优先级决定了浏览器在处理网络请求时的顺序和优先级。以下是Chrome
浏览器中网络请求的5
个优先级:
-
最高优先级(
Highest
): 该优先级通常用于处理关键资源,如页面的主要HTML
、JavaScript
和CSS
文件。这些资源对于页面的加载和渲染至关重要。 -
较高优先级(
High
): 该优先级通常用于处理一些重要的资源,如页面中需要立即展示的图片、字体等。 -
默认优先级(
Medium
): 大多数网络请求的默认优先级,包括大多数的静态资源和异步加载的资源。 -
较低优先级(
Low
): 该优先级通常用于处理一些不太重要的资源,如异步统计脚本、广告等。 -
最低优先级(
Lowest
): 该优先级通常用于处理一些可延迟加载的资源,如某些后台任务、预取资源等。
这些优先级可以帮助浏览器更好地处理网络请求,确保关键资源能够尽快加载并渲染,提高用户的页面加载体验。在实际开发中,可以通过设置合适的资源加载优先级来优化页面加载性能。
我们可以Chrome
浏览器的开发者工具,在 Network
面板中可以看到每一个请求的优先级,如下图所示。
如果你发现你的浏览器没有上图选中的列表,试试右键面板,然后访问下图所示的菜单项进行开启。
六、问题
6.1 如何正确使用 prefetch 和 preload ?
对 preload
使用 as
属性,不然将不会从中获益。如果在指定要 preload
的内容(例如脚本)时未提供有效的 as
,则最终将获取两次。
这是工具的一个很好的例子,而不是规则。 preload
的文件数量取决于加载其他资源时网络内容、用户的带宽和其他网络状况。尽早 preload
页面中可能需要的文件,对于脚本,preload
你的关键模块是很好的,因为它将获取与执行分开,而仅仅使用 <script async>
不会这样做,因为它会阻止窗口的 onload
事件。你可以 preload
图像、样式、字体和媒体。最重要的是,作为一名页面作者,你可以更好地控制提前获取页面所需要的信息。
6.2 可以使用 preload 让 CSS 样式立即生效吗?
当然可以,preload
支持基于异步加载的标记,使用 <link rel=”preload”>
的样式表可以使用 onload
事件立即应用于当前文档:
<link rel="preload" href="style.css" onload="this.rel=stylesheet">
6.3 prefetch 可以作为 preload 的后备方案吗?
不要用 prefetch
作为 preload
的后备方案 ,它们适用于不同的场景,常常会导致不符合预期的二次获取。使用 preload
来获取当前需要任务否则使用 prefetch
来获取将来的任务,不要一起用。
6.4 如何判断 <link rel="preload">
的支持情况?
以下的代码段可以判断 <link rel=”preload”>
支持情况:
const preloadSupported = () => {
const link = document.createElement('link');
const relList = link.relList;
if (!relList || !relList.supports)
return false;
return relList.supports('preload');
};
FilamentGroup
也有一个 preload
检测器 ,作为他们的异步 CSS
加载库 loadCSS
的一部分。
6.5 preload 或者 prefetch 什么情况下会导致二次获取?
-
将
prefetch
作为preload
的后备方案来使用, 它们适用于不同的场景,常常会导致不符合预期的二次获取。 -
如果在指定要
preload
的内容(例如脚本)时未提供有效的as
,则最终将获取两次。 -
preload
字体不带crossorigin
也将会二次获取, 确保在使用preload
获取字体时添加crossorigin
属性,否则将二次下载。 他这个请求使用匿名的跨域模式。 即使字体与页面位于同个域 下,也建议使用。也适用于其他域名的获取(比如说默认的异步获取)。
6.6 可以用 HTTP2 的服务器推送来代替 preload 吗?
当你知道资源的精确加载顺序时使用推送,并让 service worker
拦截可能导致再次推送缓存资源的请求。 使用 preload
可以使资源的开始下载时间更接近初始请求 - 这对所有的资源获取都有用。
我们假设浏览器正在加载一个页面,页面中有个 CSS
文件,CSS
文件又引用一个字体库,对于这样的场景,
若使用 HTTP/2 PUSH
,当服务端获取到 HTML
文件后,知道以后客户端会需要字体文件,它就立即主动地推送这个文件给客户端,如下图:
而对于 preload
,服务端就不会主动地推送字体文件,在浏览器获取到页面之后发现 preload
字体才会去获取,如下图:
虽然推送很有效,但它不像 preload
那样对所有的情况都适应。
推送不能用于第三方资源的内容,通过立即发送资源,它还有效地缩短浏览器自身的资源优先级情况。在你明确的知道在做什么时,这应该会提高你的应用性能,如果不是很清晰的话,你也许会损失掉部分的性能。
6.7 Js 中自定义的 preload 与原本的 rel = preload 有什么区别?
preload
解耦从 JS
处理和执行中获取资源。 因此,preload
在标记中声明以被 Chrome preload
扫描器扫描。 这意味着在许多情况下,在 HTML
解析器甚至到达标签之前,将获取预加载(具有指示的优先级),这使它比自定义预加载实现更强大。
6.8 preload 请求头是什么?它与 preload 标签相比如何?它与 HTTP2 服务器推送有什么关系?
与其他类型的链接一样,preload
链接即可以使用 HTML
标记 或 HTTP
标头。 在任何一种情况下,preload
链接都会指示浏览器开始将资源加载到内存缓存中,这表明该页面有很高可能性使用该资源,并且不希望等待预加载扫描程序或解析程序发现它。
当金融时报在它们的网站使用 preload HTTP
头时,他们节约了大约 1s
的显示片头图片时间。
如上所示: 1
没有使用 preload
, 2
使用了 preload
你可以使用任何一种形式提供 preload
链接,但是你应该知道一个重要区别:如规范所允许的,许多服务器在遇到 HTTP
头的 preload
链接时会触发 HTTP/2
服务器推送。 HTTP/2
推送的性能影响不同于普通的预加载,所以你要确保没有发起不必要的推送。
你可以使用 preload
标签来代替 preload
头以避免不必要的推送,或者在你的 HTTP
头上加一个 nopush
属性。