Speculation Rules API 详解:提升 MPA 性能的利器
简介
Speculation Rules API 是一个浏览器 API,旨在通过预测用户可能的下一步导航,提前加载或渲染页面,从而显著提升多页面应用(MPA)的性能。用一句话概括:它通过预取或预渲染下一个页面,让用户感觉导航几乎是瞬时的。
两种加载方式
-
Prefetch(预取)
仅下载页面的 HTML 资源,不执行渲染或加载子资源(如 CSS、JS 或图片)。
适用场景:用户可能访问的页面,例如文章列表中的"下一页"。 -
Prerender(预渲染)
下载并完全渲染页面,包括所有子资源和 JavaScript 的执行。
适用场景:用户极大概率会访问的页面,例如电商网站中的"结账"页面。
如何调试
在浏览器中按 F12
打开开发者工具,切换到"应用"面板,找到"推测加载"选项,即可查看页面预取或预渲染的链接及其状态。
基本使用
基本用法
以下是一个简单的 Speculation Rules API 配置示例,展示了如何同时使用 prefetch
和 prerender
:
html
<script type="speculationrules">
{
"prefetch": [
{
"urls": ["/next.html", "/next2.html"],
"requires": ["anonymous-client-ip-when-cross-origin"],
"referrer_policy": "no-referrer"
}
],
"prerender": [
{
"where": {
"and": [
{ "href_matches": "/*" },
{ "not": { "href_matches": "/logout" } },
{ "not": { "href_matches": "/*\\?*(^|&)add-to-cart=*" } },
{ "not": { "selector_matches": ".no-prerender" } },
{ "not": { "selector_matches": "[rel~=nofollow]" } }
]
}
}
]
}
</script>
prefetch
:指定预取/next.html
和/next2.html
,并设置隐私和引用策略。prerender
:对符合条件的链接进行预渲染,排除特定页面(如退出登录或购物车)。
配置项详解
以下是常用的配置参数及其含义:
参数 | 可选值 | 默认值 | 作用 | 示例 |
---|---|---|---|---|
source |
list , document |
无 | list 匹配 urls ,document 匹配 where |
"source": "list" |
urls |
URL 数组 | 无 | 指定预取或预渲染的目标 URL | "urls": ["/next-page"] |
eagerness |
conservative , moderate , eager |
conservative |
控制触发时机:conservative (悬停/点击时)、moderate (鼠标触碰)、eager (立即) |
"eagerness": "moderate" |
requires |
anonymous-client-ip-when-cross-origin |
无 | 附加条件,如跨域时匿名化客户端 IP | "requires": ["anonymous-client-ip"] |
referrer_policy |
no-referrer , same-origin , origin , strict-origin-when-cross-origin |
无 | 设置请求的引用策略 | "referrer_policy": "no-referrer" |
where |
href_matches , selector_matches , not , and , or |
无 | 定义匹配条件,支持 URL 模式和 CSS 选择器 | 见上方示例 |
注意事项:
urls
和where
互斥,一个规则只能使用其一。source
可省略,浏览器会根据urls
或where
自动推断。prefetch
和prerender
的配置项通用。- 一个页面可配置多个规则,但浏览器最多预渲染 10 个子页面。
配置方式
-
静态 JSON
直接嵌入
<script type="speculationrules">
,适合静态内容页面(如博客)。示例见"基本用法"。
-
JS 动态添加
根据浏览器支持情况动态添加规则,支持优雅降级。
javascriptif (HTMLScriptElement.supports && HTMLScriptElement.supports("speculationrules")) { const specScript = document.createElement("script"); specScript.type = "speculationrules"; specScript.textContent = JSON.stringify({ "prefetch": [ { "source": "list", "urls": ["/next.html"] } ] }); document.body.appendChild(specScript); } else { const link = document.createElement("link"); link.rel = "prefetch"; link.href = "/next.html"; document.head.appendChild(link); }
-
外部导入
将规则托管为 JSON 文件,通过服务器响应头加载,适合动态更新。
-
服务器响应头 :
Speculation-Rules: "/rules.json"
-
JSON 示例 :
json{ "prefetch": [ { "source": "list", "urls": ["/about", "/products"], "eagerness": "moderate" } ], "prerender": [ { "source": "list", "urls": ["/checkout"], "eagerness": "eager" } ] }
-
进阶使用
规则分层
通过分层规则,可以更灵活地控制预取和预渲染行为。以下是一个分层示例:
html
<script type="speculationrules">
{
"prefetch": [
{
"where": { "selector_matches": "[data-prefetch='']" },
"eagerness": "eager"
},
{
"where": {
"and": [
{ "href_matches": "/*" },
{ "not": { "selector_matches": "[data-prefetch=false]" } }
]
},
"eagerness": "moderate"
}
],
"prerender": [
{
"where": { "selector_matches": "[data-prefetch=prerender]" },
"eagerness": "eager"
},
{
"where": { "selector_matches": "[data-prefetch='']" },
"eagerness": "moderate"
}
]
}
</script>
页面使用
在 HTML 中通过 data-prefetch
属性控制链接行为:
<a href data-prefetch>Prefetched Link</a>
:立即预取,悬停时预渲染。<a href data-prefetch="prerender">Prerendered Link</a>
:立即预渲染。<a href data-prefetch="false">Untouched Link</a>
:禁用预取/预渲染。
动态调整 :
通过 JavaScript 修改 data-prefetch
值,实现按需升级:
javascript
document.querySelector("a").dataset.prefetch = "prerender";
总结
Speculation Rules API 提供了一种强大的方式来优化 MPA 的导航性能。通过合理配置 prefetch
和 prerender
,结合规则分层和动态调整,你可以为用户带来更快的页面切换体验。无论是静态网站还是复杂应用,这项技术都值得一试!