← 全部文章

Islands 架構——Astro 的 Partial Hydration 原理

問題的起點

在傳統的 SPA 框架中,頁面渲染的流程是這樣的:

  1. 伺服器返回一個空的 HTML(或帶有內容的 SSR HTML)
  2. 瀏覽器下載整個框架的 JavaScript runtime
  3. 框架執行 hydration —— 為 DOM 元素綁定事件處理器
  4. 頁面才變得可互動

問題在於:如果頁面上只有一個按鈕需要互動,為什麼要為整個頁面執行 hydration?

Islands 架構的核心思想

Islands 架構將頁面上的互動元素視為獨立的「島嶼」,每個島嶼:

  • 擁有自己的 JavaScript bundle
  • 獨立載入和初始化
  • 不影響周圍的靜態 HTML

島嶼之外的部分是純靜態 HTML,永遠不會被 JavaScript 觸碰。

┌─────────────────────────────────┐
│         靜態 HTML 標題            │
├─────────────────────────────────┤
│    ┌───────────┐                │
│    │  🏝️ React  │  靜態內容     │
│    │  購物車     │                │
│    └───────────┘                │
├─────────────────────────────────┤
│    ┌───────────┐                │
│    │  🏝️ Vue   │                 │
│    │  搜尋欄    │   靜態文字     │
│    └───────────┘                │
└─────────────────────────────────┘

Astro 中的實現

在 Astro 中,你使用 client:* 指令來控制組件何時載入 JavaScript:

<!-- 靜態:完全在伺服器渲染,不發送 JS -->
<MyComponent />

<!-- 頁面載入後立即 Hydrate -->
<MyComponent client:load />

<!-- 進入可視區域時 Hydrate -->
<MyComponent client:visible />

<!-- 瀏覽器空閒時 Hydrate -->
<MyComponent client:idle />

<!-- 媒體查詢匹配時 Hydrate -->
<MyComponent client:media="(min-width: 768px)" />

<!-- 僅在與該元素互動時 Hydrate -->
<MyComponent client:only="react" />

與 React Server Components 的對比

React Server Components(RSC)和 Astro Islands 看似相似,但理念不同:

對比維度 Astro Islands React Server Components
框架鎖定 多框架(React/Vue/Svelte/Solid) 僅 React
互動粒度 組件級別 組件級別
傳輸協議 客戶端 JavaScript bundle 串流 JSON + 客戶端 React
靜態內容 純 HTML,零 JS 需串流客戶端 React runtime
學習曲線 低,接近 HTML 需理解 Suspense、use client 等概念

為什麼這很重要?

效能測試顯示,對於內容網站:

  • 減少 50-90% 的 JavaScript 傳輸量
  • First Contentful Paint(FCP)平均降低 40%
  • Time to Interactive(TTI)平均降低 60%

數據背後的原因很簡單:JavaScript 是當今網頁效能的最大瓶頸。下載、解析和執行 JS 都需要時間,在移動設備上尤其明顯。

何時使用哪種策略

<!-- 首屏以上、關鍵互動 → client:load -->
<Header client:load />

<!-- 折疊以下 → client:visible -->
<Comments client:visible />

<!-- 非關鍵 → client:idle -->
<AnalyticsDashboard client:idle />

<!-- 純靜態 → 不加任何指令 -->
<ArticleContent />

結語

Islands 架構不是一個全新的概念,但 Astro 把它落實到了實用層面。它讓開發者可以精確控制 JavaScript 的載入策略,而不需要為此學習一套複雜的系統。對於內容為主的網站來說,這可能是目前最合理的架構選擇。