Astro 系列(三):Island 架构——为什么默认零 JavaScript

Astro 入门与实战 系列导航

  1. (一)Astro 是什么,解决什么问题
  2. (二)项目结构与开发约定
  3. (三)Island 架构——为什么默认零 JavaScript ← 当前
  4. (四)内容驱动还是应用驱动——Astro 的边界
  5. (五)SSR 还是 SSG,怎么选
  6. (六)集成生态——从官方到社区
  7. (七)能用 Astro 做什么——扩展玩法全景
  8. (八)View Transitions——让 MPA 拥有 SPA 体验
  9. (九)Middleware、API 端点与认证
  10. (十)第三方服务拼装——评论、搜索、分析
  11. (十一)框架对比(上)——全栈方向
  12. (十二)框架对比(下)——静态站点方向
# Island 架构深度理解 ## 水合作用的问题 ### 什么是水合 ### 为什么水合昂贵 ### 全量水合的浪费 ## 岛屿架构原理 ### 静态海洋 ### 交互岛屿 ### 独立水合 ### 零 JS 默认 ## client 指令 ### client:load ### client:idle ### client:visible ### client:media ### client:only ### 指令选择策略 ## 框架组件作为岛屿 ### React 岛屿 ### Vue 岛屿 ### Svelte 岛屿 ### Solid 岛屿 ### 多框架混用 ## 何时不用岛屿 ### 全 SPA 场景 ### 组件间频繁通信 ### 状态共享需求

水合作用:为什么它是问题

水合(Hydration)是服务端渲染框架的核心机制:服务端生成 HTML,客户端下载 JavaScript 后,React/Vue 遍历每个 DOM 节点,绑定事件监听器、初始化状态,让静态 HTML "活过来"。

这个过程的问题在于:

  • CPU 消耗:每个组件都要执行水合,即使它没有交互
  • 阻塞渲染:水合是同步过程,期间用户无法交互
  • 浪费带宽:下载了大量 JS,但大部分组件的功能用户根本用不到

对于一个博客文章页面来说,除了评论区和导航菜单,99% 的 DOM 节点不需要任何交互。但传统的 SSR 框架会对整个页面进行水合。

岛屿架构:只激活需要交互的部分

Astro 的方案是把页面看作"静态海洋 + 交互岛屿":

  • 页面主体(海洋)是纯 HTML,永远不会被水合
  • 交互组件(岛屿)独立加载、独立水合
  • 岛屿之间互不干扰

这使得性能显著提升:

  • JS 体积:只传输需要交互的组件代码
  • 水合开销:只执行需要交互的组件的水合
  • 并行性:多个岛屿可以并行水合,不互相阻塞

client 指令:控制岛屿的激活时机

Astro 提供了五个 client:* 指令来控制组件何时激活:

client:load — 页面加载后立即水合。适用于高优先级交互组件,如导航栏、购物车按钮。

client:idle — 浏览器空闲时水合。适用于次要交互组件,如反馈按钮、分享面板。它利用 requestIdleCallback,不影响首屏性能。

client:visible — 组件进入视口时水合。适用于页面下方的交互组件,如下拉加载、底部表单。它是懒加载 + 按需水合的结合。

client:media — 匹配媒体查询时水合。适用于响应式组件,如移动端菜单——桌面端根本不需要。

client:only — 跳过服务端渲染,仅在客户端渲染。适用于依赖浏览器 API 的组件,如使用 localStoragewindow 对象的组件。

每个指令背后是对"何时需要交互"这个问题的精确回答。默认行为(不加指令)是永不水合——组件在服务端渲染成纯 HTML,不发送任何 JS。

多框架混用:BYOF 的真正威力

Astro 不捆绑任何 UI 框架。你可以在同一个项目中:

  • 用 React 写评论区(生态成熟、第三方库多)
  • 用 Svelte 写图表组件(轻量、性能好)
  • 用 Vue 写表单(渐进式增强方便)
  • 用 Solid 写实时数据面板(细粒度响应式)

每个框架组件都是独立岛屿,有自己的水合时机和 JS bundle。这种"微前端"式的组合在过去需要复杂的配置,在 Astro 中是默认行为。

岛屿架构的边界

不是所有场景都适合岛屿架构:

  • 组件间需要频繁通信(如拖拽排序列表)——跨越岛屿的通信成本高
  • 需要全局状态管理(如 Redux store 跨页面)——岛屿之间天然隔离
  • 纯 SPA 应用(如在线文档编辑器)——几乎所有内容都需要交互

这些场景更适合 Next.js App Router 或 SvelteKit 的全量水合模式。

延伸阅读

实操清单

  • 在 Astro 项目中创建一个 React 或 Vue 组件
  • 分别尝试 client:loadclient:idleclient:visible,观察浏览器 DevTools 中 JS 加载时机的差异
  • 用 Lighthouse 对比加和不加 client:load 的页面性能
  • 思考自己项目中有哪些组件其实不需要 JS

created by:codex on deepseek v4 pro