Speculation Rules API 详解:提升 MPA 性能的利器

310 阅读3分钟

Speculation Rules API 详解:提升 MPA 性能的利器

简介

Speculation Rules API 是一个浏览器 API,旨在通过预测用户可能的下一步导航,提前加载或渲染页面,从而显著提升多页面应用(MPA)的性能。用一句话概括:它通过预取或预渲染下一个页面,让用户感觉导航几乎是瞬时的。

两种加载方式

  • Prefetch(预取)
    仅下载页面的 HTML 资源,不执行渲染或加载子资源(如 CSS、JS 或图片)。
    适用场景:用户可能访问的页面,例如文章列表中的“下一页”。

  • Prerender(预渲染)
    下载并完全渲染页面,包括所有子资源和 JavaScript 的执行。
    适用场景:用户极大概率会访问的页面,例如电商网站中的“结账”页面。

如何调试

在浏览器中按 F12 打开开发者工具,切换到“应用”面板,找到“推测加载”选项,即可查看页面预取或预渲染的链接及其状态。

基本使用

基本用法

以下是一个简单的 Speculation Rules API 配置示例,展示了如何同时使用 prefetchprerender

<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:对符合条件的链接进行预渲染,排除特定页面(如退出登录或购物车)。

配置项详解

以下是常用的配置参数及其含义:

参数可选值默认值作用示例
sourcelist, documentlist 匹配 urlsdocument 匹配 where"source": "list"
urlsURL 数组指定预取或预渲染的目标 URL"urls": ["/next-page"]
eagernessconservative, moderate, eagerconservative控制触发时机:conservative(悬停/点击时)、moderate(鼠标触碰)、eager(立即)"eagerness": "moderate"
requiresanonymous-client-ip-when-cross-origin附加条件,如跨域时匿名化客户端 IP"requires": ["anonymous-client-ip"]
referrer_policyno-referrer, same-origin, origin, strict-origin-when-cross-origin设置请求的引用策略"referrer_policy": "no-referrer"
wherehref_matches, selector_matches, not, and, or定义匹配条件,支持 URL 模式和 CSS 选择器见上方示例

注意事项

  1. urlswhere 互斥,一个规则只能使用其一。
  2. source 可省略,浏览器会根据 urlswhere 自动推断。
  3. prefetchprerender 的配置项通用。
  4. 一个页面可配置多个规则,但浏览器最多预渲染 10 个子页面。

配置方式

  1. 静态 JSON
    直接嵌入 <script type="speculationrules">,适合静态内容页面(如博客)。
    示例见“基本用法”。

  2. JS 动态添加
    根据浏览器支持情况动态添加规则,支持优雅降级。

    if (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);
    }
    
  3. 外部导入
    将规则托管为 JSON 文件,通过服务器响应头加载,适合动态更新。

    • 服务器响应头Speculation-Rules: "/rules.json"
    • JSON 示例
      {
        "prefetch": [
          {
            "source": "list",
            "urls": ["/about", "/products"],
            "eagerness": "moderate"
          }
        ],
        "prerender": [
          {
            "source": "list",
            "urls": ["/checkout"],
            "eagerness": "eager"
          }
        ]
      }
      

进阶使用

规则分层

通过分层规则,可以更灵活地控制预取和预渲染行为。以下是一个分层示例:

<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 值,实现按需升级:

document.querySelector("a").dataset.prefetch = "prerender";

总结

Speculation Rules API 提供了一种强大的方式来优化 MPA 的导航性能。通过合理配置 prefetchprerender,结合规则分层和动态调整,你可以为用户带来更快的页面切换体验。无论是静态网站还是复杂应用,这项技术都值得一试!