如何實現 0 毫秒無感頁面跳轉?聊聊被低估的 Speculation Rules API

![如何實現 0 毫秒無感頁面跳轉?聊聊被低估的 Speculation Rules API](https://i.imgur.com/J0ZRhxh.jpeg)

我們花了整整十年的時間,用各種複雜的單頁應用程式(SPA)框架、客戶端路由預載,以及冗長的動態 import 分包,試圖讓網頁的跳轉看起來像原生 App 一樣瞬間呈現。

甚至在 Next.js 或者 Nuxt.js 這樣的現代框架裡,我們預設信任它們的動態預取機制(Prefetching),哪怕這會經常把瀏覽器的網路面板塞滿成百上千個小 JS 分片,耗費大量的使用者頻寬。

但在這行業敲了快十年的程式碼,看了太多為了 體感速度 而拼命堆砌的複雜基建。我發現很多團隊都在無腦跟風做過度設計,卻忽略了瀏覽器原生技術裡最強大的 API。

今天聊聊一個在 2026 年已經被主流瀏覽器原生支援、被嚴重低估的 Web 標準 —— Speculation Rules API(推測規則 API)

它不需要你寫一行繁瑣的客戶端路由邏輯,直接利用瀏覽器的閒置算力,實現物理意義上絕對的 0 毫秒無感秒開


1. 0 毫秒秒開的底層原理

在聊它之前,我們得先釐清兩個概念:預取(Prefetch)預渲染(Prerender)

ChatGPT Image 2026年5月26日 10_59_45.png

傳統的 <link rel="prefetch"> 只是把下一頁的 HTML 靜態資源提前下載到本地快取裡。當你點擊跳轉時,瀏覽器依然要走一遍:解析 HTML -> 下載並執行 JS -> 計算版面 -> 繪製頁面 的完整生命週期。雖然快了,但依然有肉眼可見的白屏時間。

Speculation Rules API 裡的預渲染(Prerender),走得遠比你想的要極端。

當你定義了規則後,瀏覽器會在背景直接開啟一個隱形的分頁(Invisible Tab),把目標頁面完整地跑一遍:下載所有的子資源、執行所有的 JS、甚至連 DOM 樹頁面版面配置(Layout) 都直接在背景算好。

當使用者真正點下連結的一瞬間,瀏覽器直接把這個在背景已經渲染好的頁面展到螢幕上。

ChatGPT Image 2026年5月26日 11_04_18.png

大家可以透過在瀏覽器主控台輸入這行命令,可以清楚地看到這個物理秒開的鐵證:

screenshot-20260526-110645.png

javascript 体验AI代碼助手 代碼解讀複製代碼// 如果這個值大於 0,說明頁面是 0 毫秒閃現出來的,它來自瀏覽器的背景預渲染
console.log(performance.getEntriesByType('navigation')[0].activationStart);

怎麼用?別再傻傻寫死 URL 了

很多網上的早期教學只教了最基礎的靜態列表寫法(寫死一個 URL 陣列)。但在真實的動態業務裡,你根本不可能預測使用者下一個要點哪個商品。

現代 Speculation Rules API 最強大的地方在於:文件規則(Document Rules)。你可以直接透過 CSS 選擇器URL 正則模式,讓瀏覽器智慧地去猜使用者的意圖。

html 体验AI代码助手 代码解读复制代码<!-- 直接嵌入到 HTML 的極簡配置 -->
<script type="speculationrules">
{
  "prerender": [
    {
      "source": "document",
      "where": {
        "and": [
          { "href_matches": "/products/*" }, // 只預渲染商品詳情頁
          { "not": { "href_matches": "/products/cart" } }, // 排除購物車等敏感頁面
          { "selector_matches": "a.product-link" } // 只針對特定類名的連結生效
        ]
      },
      "eagerness": "moderate" // 觸發時機
    }
  ]
}
</script>

ChatGPT Image 2026年5月26日 11_07_39.png

注意裡面這個極其關鍵的參數:eagerness(飢渴度/觸發時機)。它有四個檔位,代表了你對效能和頻寬的權衡:

  • conservative(保守):只有在使用者按下滑鼠(mousedown)或按住觸控螢幕的一瞬間才觸發。這給瀏覽器留了大約 100~200ms 的空檔期,雖然時間短,但絕對不會浪費使用者流量。
  • moderate(溫和):當使用者滑鼠懸停(hover)在連結上超過 200ms,或者在行動端滑過連結時觸發。這是絕大多數中後台和獨立站的黃金平衡點。
  • eager(熱切):只要連結進入檢視區(Viewport)或者一載入就瘋狂預渲染。除非你對伺服器頻寬非常有自信,且使用者全在寬頻環境下,否則別輕易用。

必踩坑指南,藏在 0ms 後面的三個致命問題

寫出上面的配置,任何一個剛畢業的開發自學半天也能搞定。但如果直接上線,你大概率會親手製造一起線上事故🤣。

我給你盤盤這三個連大廠開發都經常翻車的細節。

1.流量與統計污染(Analytics Double-Fire)

因為預渲染是在背景 靜默執行 了完整的 JS 邏輯,這就意味著:如果你的數據埋點(如 Google Analytics、自研神策系統)寫在元件的 mounted 階段,它會在使用者還沒點擊頁面時,就直接上報一次 PageView。

這會導致你們公司的業務轉換率、UV 統計直接出現災難性的偏差。

破局方法:可以利用 document.prerendering 進行埋點攔截:

javascript 体验AI代码助手 代码解读复制代码// 防範靜默預渲染導致的統計污染
function trackPageView() {
  if (document.prerendering) {
    // 如果目前處於背景靜默渲染階段,絕對不上報
    // 而是註冊事件,等待使用者真正點擊啟用頁面後再觸發
    document.addEventListener('prerenderingchange', () => {
      sendTelemetry(); // 真正展現給使用者時才發送打點
    }, { once: true });
  } else {
    // 正常跳轉,直接上報
    sendTelemetry();
  }
}

2.狀態滯後與庫存髒資料

設想一下:使用者在列表頁 A 瀏覽,瀏覽器在背景靜默預渲染了詳情頁 B。此時,使用者在 A 頁面把商品加入了購物車。然後點擊進入 B 頁面。因為 B 頁面是在幾分鐘前就 在背景渲染好 的,它裡面的購物車數量、甚至庫存狀態,依然保留著幾分鐘前的舊資料。

可以先檢測啟用狀態,動態更新髒資料:

javascript 体验AI代码助手 代码解读复制代码// 檢測頁面是否是透過啟用無感跳轉進來的
const navEntry = performance.getEntriesByType('navigation')[0];

if (navEntry && navEntry.activationStart > 0) {
  // 說明這個頁面是在背景載入過的,我們需要局部刷新那些易變的狀態
  refreshCartCount();
  refreshInventoryStatus();
}

3.破壞單例與伺服器壓力雪崩

如果你的頁面有複雜的動態 API 請求,比如一進頁面就拉取個人化推薦。一旦你開啟了 eager 或者 moderate 預渲染,意味著使用者每次滑動螢幕,你的伺服器都會承受數倍於平時的 API 請求壓力。

對於小團隊來說,這會直接把你們脆弱的 Node 伺服器端或者雲資料庫打掛。

所以,核心業務(如支付、下單)嚴禁開啟 prerender,最多只能開啟輕量級的 prefetch(只下 HTML,不執行 JS)。

4.瀏覽器相容性

到目前2026年5月,主流瀏覽器已經開始支援新特性。但是 Safari 瀏覽器還沒得到支援。大家選擇的時候還是得謹慎(當然對於不支援的瀏覽器,可以使用其他回退方案🤔)

screenshot-20260526-113019.png


讓瀏覽器幹它該幹的事

在過去咱們為了提速,在 React/Vue 路由裡寫了成百上千行的預載邏輯,把工程搞得無比臃腫,還要時刻提防主執行緒卡頓。

但歷史的規律一直在證明:任何在框架層拼命掙扎的複雜基建,最終都會被 Web 原生標準降維打擊😁。

Speculation Rules API 的出現,我們只需要給出一份輕量級的 JSON 配置,剩下的多執行緒調度、頻寬節流、安全沙盒隔離,全部交由 C++ 撰寫的底層引擎去搞定,後面的事情咱們就不用操心👋。

把精力放回到真正的業務邏輯和邊界防禦上。用最輕量的原生標準,給使用者換來極致的、物理意義上的秒開體驗。

分享完畢!

溜了溜了溜了溜了.gif


原文出處:https://juejin.cn/post/7643721690566688804


精選技術文章翻譯,幫助開發者持續吸收新知。

共有 0 則留言


精選技術文章翻譯,幫助開發者持續吸收新知。
🏆 本月排行榜
🥇
站長阿川
📝21   💬4   ❤️1
617
🥈
alicec
📝1   ❤️2
86
#4
我愛JS
💬1  
3
評分標準:發文×10 + 留言×3 + 獲讚×5 + 點讚×1 + 瀏覽數÷10
本數據每小時更新一次
📢 贊助商廣告 · 我要刊登