群岛架构深入:Islands 与部分水合
本教程共 56 篇 · 第 26 篇 · 更新于 2026-08-07 · 约 8 分钟阅读
本节目标:搞懂 Astro 为什么默认就快,岛屿(island)到底是什么,部分水合(partial hydration)又是怎么把多余的 JavaScript 省下来的。
一句话理解群岛架构
群岛架构(Islands Architecture)是 Astro 的核心思路。它把页面大部分内容渲染成快速、静态的 HTML,只在需要交互或有个性化内容的地方,插入一小块一小块带 JavaScript 的「岛屿」。
你可以把整张页面想象成一片平静的「静态 HTML 海洋」,上面漂浮着几个会动的「岛屿」。海洋负责展示文字、图片这些不需要交互的内容;岛屿才负责轮播图、弹窗、登录头像这些需要 JavaScript 的地方。
这种思路避免了大多数现代 JavaScript 框架的通病:一上来就把整张网站打包成一个巨大的 JS 应用,拖慢加载速度。
群岛架构是怎么来的
「组件岛屿」这个说法,最早是 Etsy 前端架构师 Katie Sylor-Miller 在 2019 年提出的。后来 Preact 的创始人 Jason Miller 在 2020 年写了一篇文章,把这套想法整理记录了下来。
他当时的原话大意是:先在服务端把 HTML 页面渲染出来,然后在高度动态的区域周围「注入占位符或插槽」,这些内容之后可以在客户端被「水合」成独立的小部件,并复用服务端最初渲染的 HTML。
这套架构依赖的技术,也叫「部分水合(partial hydration)」或「选择性水合(selective hydration)」。
作为对比,大多数基于 JavaScript 的框架会把整站当成一个巨大的 JS 应用来水合、渲染。这正是单页应用(SPA)的做法。SPA 很强大,但因为客户端 JS 太重,页面加载性能往往吃亏。
Astro 是第一个把选择性水合内置进来的主流 JS 框架。它用的就是 Sylor-Miller 提出的这套岛屿模式,后来又做了扩展,连服务端动态渲染的内容也能用上类似思路。
什么是「岛屿」
在 Astro 里,岛屿就是「漂浮在一片静态 HTML 海洋中的、被增强了的 UI 组件」。它本身是一个交互组件,但周围的页面是静态的。
岛屿分两种,这点要记牢:
- 客户端岛屿(client island):一个交互式 JS 组件,它会和页面其余部分分开进行水合(hydrate)。比如一个会动的轮播图。
- 服务端岛屿(server island):一个 UI 组件,它的动态内容是在服务端单独渲染的。比如登录用户自己的头像。
两者都把「昂贵或较慢」的过程,按组件为单位独立处理,从而优化整页加载。
岛屿组件长什么样
Astro 组件是页面模板的基本积木。它本身只渲染成静态 HTML,不依赖任何客户端运行时。
你可以把客户端岛屿想成「漂浮在静态 HTML 海洋中的交互小部件」。而服务端岛屿,则用来放那些个性化或服务端渲染的动态元素,比如已登录访客的头像。
一个典型的页面,可能长这样:
- 顶部导航(交互式岛屿)
- 侧边栏(静态 HTML)
- 正文文字、图片(静态 HTML)
- 图片轮播(交互式岛屿)
- 页脚(静态 HTML)
每个岛屿都和页面上其他岛屿「隔离」运行。一个岛屿卡住,不影响别的岛屿。而且多个岛屿可以共存一页,它们之间还能共享状态、互相通信,哪怕运行在不同的组件上下文里。
这种灵活性,让 Astro 能同时支持 React、Preact、Svelte、Vue、SolidJS 等多种 UI 框架。因为它们彼此独立,你甚至可以在同一个页面里混用好几个框架。
部分水合:Astro 替你省 JS 的关键
「水合(hydration)」这个词,指的是把一段静态的 HTML,重新接上 JavaScript 逻辑,让它变成可以点击、可以响应事件的「活」组件。
Astro 默认会把 UI 组件只渲染成 HTML 和 CSS,自动剥掉所有客户端 JavaScript。
---
import MyReactComponent from '../components/MyReactComponent.jsx';
---
<MyReactComponent />
上面这行代码,在默认情况下只会输出静态 HTML,不会带任何 JS。听起来有点「死板」,但这正是 Astro 网站默认就快的原因,也防止开发者不小心发太多 JS 拖慢网站。
想让一个静态组件变成「会动」的岛屿,只需要加一个 client:* 客户端指令。Astro 就会自动帮你打包对应的客户端 JS,做到性能最优。
---
import MyReactComponent from '../components/MyReactComponent.jsx';
---
<!-- 这个组件现在在页面上可交互了!其余网站依旧是静态的。 -->
<MyReactComponent client:load />
有了岛屿机制,客户端 JS 只会在你明确标记的、需要交互的组件上加载。而且因为交互是「按组件」配置的,你可以给每个组件安排不同的加载优先级。
比如 client:idle 表示浏览器空闲时再加载;client:visible 表示组件进入视口才加载。如果那个轮播图很重,用户又一直没滚到它,那它干脆就不加载。
群岛架构带来的好处
最明显的好处是性能。页面大部分被转成快速的静态 HTML,只有真正需要的组件才加载 JS。而 JS 恰恰是「按字节算最慢」的资源之一,能省则省。
另一个好处是并行加载。前面例子里的「图片轮播」优先级低,它不需要阻塞优先级高的「顶部导航」。两者并行加载、各自独立水合。导航能立刻变可交互,不用等下方更重的轮播。
更妙的是,你能精确告诉 Astro 每个组件该怎么、何时渲染。哪个组件贵,就让它「进入视口才加载」。用户看不到,它就不加载。
说到底,岛屿由你这位开发者显式决定:哪些组件需要在浏览器里跑。Astro 只水合页面真正需要的部分,其余统统留作静态 HTML。
Note客户端岛屿是 Astro「默认就快」的秘密武器。它不是魔法,而是把「要不要发 JS」的决定权交还给了你。
小结
群岛架构用「静态海洋 + 动态岛屿」的方式,把 JS 控制在最小范围。客户端岛屿负责交互,服务端岛屿负责动态内容。下一章我们专门拆开讲,那些 client:* 指令到底怎么用。