若要提升用户在网站中浏览时的网页加载性能,最有效的方法之一是在用户访问下一个网页之前,就开始加载该网页。这可以通过一种称为“推测加载”的技术来实现,该技术使用 Speculation Rules API。
运作方式
推测加载的工作原理是使用基于 JSON 的推测规则,告知浏览器哪些链接可以预提取或预渲染,从而在用户点击这些链接时提升网页加载性能。
这些规则可以是硬编码的网址列表(urls 键,称为列表规则),也可以是包含一组 href 和 CSS 选择器的 where 键,用于在网页上查找链接(称为 document 规则)。
规则还可以包含可选的 eagerness 属性,用于指定何时应预提取或预渲染网页。eagerness 属性可以设置为 immediate、eager、moderate 或 conservative。immediate 会尽快推测,而其他模式则会分别等待用户信号,例如悬停一小段时间、悬停较长时间或开始点击网页。
规则可以与不同的 Eagerness 设置结合使用,以便在用户互动较多时先积极预提取,然后再预渲染。
适用情形
推测加载对于静态网页尤其有用,因为这些网页的内容不太可能经常更改,而且生成成本较低,尤其是在边缘缓存时。它也可用于动态网页,但请务必注意内容过时的可能性。
推测加载通常用于同源链接,但更高级的选项允许进行一些跨域推测。本指南重点介绍更常见的同源用例。
对于接下来可能访问的网页,例如资讯标题文章或分步流程(如学习课程)中的下一页,更积极的推测加载是不错的选择。
如果用户下一步的操作不太明显,或者页面上有许多链接,且每个链接被访问的可能性相同,那么不那么积极的推测加载是一个不错的选择。通过等待更多信号(例如悬停或开始点击网页),您可以抢先一步加载下一页并改善用户体验,即使该网页未完全预提取或预渲染。
同样,预提取是比预渲染更保守的选择,使用的资源更少(在客户端和服务器端),但为用户带来的好处也更少。这是初始实现的一个不错选择,后续可根据开发者的明确请求扩展到预渲染。
使用方法
推测规则采用基于 JSON 的格式,可以包含在 <script type="speculationrules"> 标记中。这些规则可以包含在文档的 <head> 或 <body> 中,也可以使用 JavaScript 动态添加。
您还可以在全局级别或针对每条规则使用 tag。设置后,此标记将包含在 Sec-Speculation-Tags 标头中,以便您在服务器端识别进行了哪些推测。
用于预提取预定义网址的简单网址列表规则示例
<script type="speculationrules">
{
"tag": "product-page-speculations",
"prefetch": [
{
"urls": ["/product/1", "/product/2", "/product/3"]
}
]
}
</script>
一个简单的文档规则示例,用于预渲染网页上的所有同源链接
<script type="speculationrules">
{
"tag": "all-links-speculations",
"prerender": [{
"where": { "href_matches": "/*" }
}]
}
</script>
复杂文档规则示例:预渲染链接,但排除互动式网站
<script type="speculationrules">
{
"tag": "speculations-with-exclusions",
"prerender": [{
"where": {
"and": [
{ "href_matches": "/*" },
{ "not": {"href_matches": "/wp-admin"}},
{ "not": {"href_matches": "/*\\?*(^|&)add-to-cart=*"}},
{ "not": {"selector_matches": ".do-not-prerender"}},
{ "not": {"selector_matches": "[rel~=nofollow]"}}
]
}
}]
}
</script>
混合规则集示例
此示例展示了一个规则集,该规则集会积极预提取所有链接,然后更进一步,在收到更多信号时,以 moderate 积极程度预渲染这些链接。
<script type="speculationrules">
{
"prefetch": [{
"tag": "prefetch-speculations",
"where": { "href_matches": "/*" },
"eagerness": "eager"
}],
"prerender": [{
"tag": "prerender-speculations",
"where": { "href_matches": "/*" },
"eagerness": "moderate"
}]
}
</script>
最佳做法
- 务必使用推测规则来预提取和预渲染用户接下来可能会访问的网页。
- 务必对静态网站使用推测规则,因为这些网站的内容不太可能经常更改,且网页生成成本较低,尤其是在边缘缓存时。
- 务必谨慎地将推测规则用于动态网页,因为这些网页的内容更可能频繁变化、可能过时,且生成成本更高。
- 建议优先使用文档规则,而不是列表规则,因为文档规则更灵活,允许在多个网页之间共享同一规则,并且可用于预提取和预渲染事先未知的网页。
- 务必考虑预提取和预渲染之间的权衡,并根据您的应用场景选择合适的方法。预渲染比预提取更耗费资源,并且在显示动态状态的复杂应用中可能会导致更多意外副作用,但可提供更好的用户体验。如果不确定,请询问开发者其偏好。
- 务必考虑不同
eagerness级别之间的权衡,并根据您的应用场景选择合适的级别。更积极的推测可提供更好的用户体验,但会使用更多资源,并且在显示动态状态的复杂应用中可能会导致更多意外副作用。如果不确定,请询问开发者其偏好。 - 请勿过度使用推测规则,例如推测网页上的每个链接。浏览器有限制(非 Eager 预加载最多 2 个)。
immediate应仅用于极少数链接。 - 请勿推测可能触发状态更改的网址(例如
/logout或/add-to-cart),如果这些网址可能包含在文档规则中,请在推测规则中明确排除它们。 - 请勿在单页应用 (SPA) 中使用推测规则。推测规则专为多页应用 (MPA) 设计,在这些应用中,浏览器会在每次导航时导航到新文档。在单页应用中,浏览器不会在每次导航时都导航到新文档,因此推测规则不会按预期运行。
浏览器支持和后备策略
不过,推测加载是一种渐进增强功能。作为增强功能,它非常安全,并且鉴于其潜在的性能优势,我们强烈建议您使用它。如果浏览器不支持推测规则,则会直接忽略这些规则。