Speculation Rules API能用于SPA网站吗?
答案是:可以。
SPA(Single-Page Application)本身的工作原理就是避免完整的页面导航。它通过 JavaScript 动态地重写当前页面的内容来模拟导航,而不是从服务器加载一个新的 HTML 文档。
因此,预渲染一个完整的 SPA 路由页面是多余且无效的,因为浏览器已经在你当前的标签页里运行着这个 SPA。
然而,Speculation Rules API 在 SPA 生态中仍然有它独特且强大的用武之地,主要体现在以下几个方面:
场景一:预获取 SPA 的路由代码分割块(主要用途)
这是 SPA 最相关、最实用的应用场景。
大多数现代 SPA 使用代码分割(Code Splitting),将不同路由的代码打包成独立的 chunk 文件(如 home.[hash].js
, settings.[hash].js
)。当用户导航时,需要先去获取并执行这个新的 JavaScript chunk,这就会带来延迟。
你可以使用 prefetch
规则来提前获取这些 chunk 文件。
<script type="speculationrules">
{"prefetch": [{"source": "document","where": {"href_matches": "/settings" // 当页面中有指向 /settings 的链接时},"eagerness": "moderate" // 用户悬停时触发}]
}
</script>
它是如何工作的:
浏览器发现了一个指向
/settings
的链接。根据规则,当用户悬停时(
moderate
eagerness),浏览器会解析该链接。它会发现导航到
/settings
需要加载一个新的 JavaScript chunk(例如settings.abc123.js
)。浏览器会仅 prefetch 这个必要的 chunk 文件,并将其存入缓存。
当用户真正点击链接时,SPA 的路由器请求这个 chunk,它会立即从磁盘缓存中加载,从而显著加快新视图的加载速度。
好处:
大幅减少路由切换延迟,特别是对于较大的代码分割包。
资源消耗极低,只下载资源,不执行 JavaScript 或渲染。
完美契合 SPA 的工作流。
场景二:从 SPA 预渲染一个独立的 MPA
如果你的 SPA 中有一个链接是跳转到一个完全独立的、传统的多页面应用(MPA)(例如,从你的 SPA 博客跳转到公司的帮助中心wiki),那么这个场景就非常适用。
在这种情况下,你可以使用 prerender
规则。
<script type="speculationrules">
{"prerender": [{"source": "list","urls": ["https://support.mycompany.com/topic/123"],"requires": ["anonymous-client-ip-when-cross-origin"]}]
}
</script>
这样,当用户从你的 SPA 跳转到帮助中心时,体验将是瞬时的。
场景三:预获取 SPA 所需的 API 数据
这是一个更超前的用法。理论上,你可以用规则预取 SPA 下一个视图所需要的数据。
编写一个简单的 API 端点,例如
/api/prefetch-settings-data
。使用
prefetch
规则指向这个端点。
<script type="speculationrules">
{"prefetch": [{"source": "list","urls": ["/api/prefetch-settings-data"]}]
}
</script>
当规则触发时,浏览器会请求这个端点并将响应缓存起来。当你的 SPA 路由到相应视图并正常调用 fetch('/api/settings-data')
时,请求可能会直接从磁盘缓存中得到响应。
注意: 这需要仔细设计 API 和缓存策略,确保预取请求和实际请求的 URL 和 headers 完全匹配,否则浏览器不会使用缓存。
总结对比表
场景 | 使用的规则 | 目的 | 对 SPA 的效益 |
---|---|---|---|
预获取路由代码块 | prefetch | 提前下载下一个路由的 JS/CSS 文件 | 非常高。显著加快路由切换速度。 |
预渲染外部 MPA | prerender | 提前完整渲染一个外部传统网站 | 中等。适用于跳出到独立站点的场景。 |
预获取 API 数据 | prefetch | 提前获取下一个视图所需的数据 | 理论可行,但实践复杂,需精心设计。 |
核心结论:
对于 SPA,不要想着用 prerender
去预渲染整个路由。你应该优先考虑使用 "prefetch"
规则来提前获取代码分割产生的 chunk 文件。这是最安全、最有效、资源利用率最高的做法,能直接解决 SPA 路由切换时的加载瓶颈。
所以,能用于 SPA 吗?能,而且很有用! 只是它的用法从“预渲染整个页面”转变为了“预获取子资源”,这同样是性能优化的一大胜利。