アイランドアーキテクチャ
- なぜ生まれた?
- 記事や商品説明が主のページでも、全体のコードを送ってハイドレーションしていた。
- 何を解決した?
- HTML はサーバーで描き、動く部品だけを島として別々に読み込んで動かした。
- 何を残した?
- どこを島にするかを前もって決める設計と、島どうしをつなぐ手間が残った。
- 登場
- 作者
- Katie Sylor-Miller、Jason Miller
- 状態
- 現役
アイランドアーキテクチャという考え方が無かったころ
Section titled “アイランドアーキテクチャという考え方が無かったころ”ニュースサイトの記事のページを思い浮かべてください。読者が来た目的は本文で、動く必要があるのは画像のカルーセルや共有のボタンくらいです。通販の商品ページでも、主役は商品の説明で、すぐに動いてほしいのは「今すぐ買う」のボタンです。 こうしたページを SPA のフレームワークで作ると、サーバーで HTML を描き、ブラウザで同じコードを動かしてつなぎ直す ハイドレーション を使うことになります。困ったのは、その範囲でした。
ページの一部しか動かないのに、なぜページ全体をハイドレーションしていたのか
Section titled “ページの一部しか動かないのに、なぜページ全体をハイドレーションしていたのか”SPA のフレームワークは、ページを1つのアプリとして扱います。Jason Miller の言い方では、いちばん外側の「ルート」の部品を先に初期化してから、その内側へ進む上から順の描画です。サーバーの HTML につなぐときも同じで、本文のように動かない部分も含めて、ページ全体のコードを読み込んで処理します。 Google の Addy Osmani と、Preact の作者の Miller が2019年2月6日に公開した「Rendering on the Web」は、この「アプリ全体を一度に初期化する」やり方に代わる手として、ページの部品ごとに段階的に、あるいは一部だけをハイドレーションする方法を挙げています。動かない部分のコードをほとんど送らずに済ませる「部分的な再ハイドレーション」については、こう書いています。
“Partial rehydration has proven difficult to implement.” (部分的な再ハイドレーションは、実装が難しいとわかってきた)
「SEO のための SSR」への不満
Section titled “「SEO のための SSR」への不満”翌2020年、Miller は自分のブログで、SPA が使うサーバー描画(SSR)の現状をこう書いています。
“SSR can actually have a net negative impact on User Experience - visitors are left waiting for the actual functionality of a page to arrive while staring at a frustratingly fake version of that page.” (SSR は利用者の体験を差し引きで悪くすることさえある。訪問者は、いらだたしい偽物のページを眺めながら、本当の機能が届くのを待たされる)
Miller によれば、SSR はしばしば検索エンジン対策(SEO)のために必要だと説明され、あとから足すものになっていました。仮想 DOM のライブラリでは、最初の描画がサーバーの HTML の DOM を壊して一から作り直してしまう状況も、気づかないうちに起きやすいと書いています。
アイランドアーキテクチャという考え方
Section titled “アイランドアーキテクチャという考え方”HTML の海に、動く島を浮かべる
Section titled “HTML の海に、動く島を浮かべる”2020年8月11日、Miller は「Islands Architecture」という記事を公開しました。考え方の中心は次の1文です。
“The general idea of an “Islands” architecture is deceptively simple: render HTML pages on the server, and inject placeholders or slots around highly dynamic regions.” (「アイランド」アーキテクチャの考え方は、拍子抜けするほど単純だ。HTML のページをサーバーで描き、動きの多い部分のまわりに場所取りの枠を入れる)
枠の中にもサーバーで描いた HTML が入っていて、ブラウザはその枠ごとに、小さな独立した部品としてハイドレーションします。Miller はこれを、静的な HTML の文書に、別々のアプリがいくつも埋め込まれている形にたとえました。 ページは1つのアプリではなく、HTML の上に独立した小さなアプリが並んだものになります。
Miller が挙げた利点は、ルートの部品を先に初期化する必要が無いことです。それぞれの島は他を待たずに動けるようになり、1つの島の性能の問題がほかの島に響きません。 サーバーの HTML の位置づけも変わります。ニュースのページなら本文、商品のページなら商品の説明が HTML にそのまま入っていればよく、そのほかの部品をどの順で動かすかは製品としての判断だ、と Miller は書いています。売り上げに直結する「今すぐ買う」ボタンは、サイトへの意見を集めるアンケートのボタンより先に動かせばよい、という例です。
「島」という名前は誰が付けたのか
Section titled “「島」という名前は誰が付けたのか”記事の書き出しで、Miller はこの名前を自分の発案とはしていません。
“To the best of my knowledge, the “Component Islands” pattern was coined by Etsy’s frontend architect Katie Sylor-Miller during a meeting we had in 2019.” (私の知るかぎり、「コンポーネントアイランド」というパターンは、2019年に私たちが行った打ち合わせで、Etsy のフロントエンドアーキテクトの Katie Sylor-Miller が名付けた)
その前の文では、ネット上に参考になる記述を見つけられなかったが、この年(2020年)にこの名前が何度も使われるのを聞いた、とも書いています。Sylor-Miller 本人が名付けについて書いた記録は、この記事では確かめられませんでした。 名前を付けたのは Sylor-Miller、考え方を文章にして広めたのは Miller、というのが Miller 自身の説明です。 Astro のドキュメントも同じ経緯を書いています。この記事は、考え方が文章で公開された2020年8月11日を登場としています。
jQuery でページに少し JavaScript を足していたころと、何が違うのか
Section titled “jQuery でページに少し JavaScript を足していたころと、何が違うのか”サーバーの HTML に、一部だけ JavaScript で動きを足すやり方は、jQuery のころからありました。Miller も、島にいちばん近いのは progressive enhancement(JavaScript が無くても読める HTML に、動きを後から足す作り方)だと書いています。
Miller は画像のカルーセルを例に、2つを比べています。
| これまでの progressive enhancement | アイランド | |
|---|---|---|
| カルーセルの HTML | ページの HTML にある | カルーセルの部品をサーバーで描く |
| 動きを足すもの | ページの中のカルーセルを探して jQuery のプラグインを当てる <script> | そのカルーセルのために出した <script> が、部品のコードを読み込んで、その場で動くものに置き換える |
Miller の言い方では、アイランドは progressive enhancement に、SSR のハイドレーションと、ページの一部に動きを足すときの一貫した考え方を加えたものです。サーバーで HTML を描くのも、ブラウザで動きを付けるのも、同じ部品のコードです。
アイランドアーキテクチャを実装した技術
Section titled “アイランドアーキテクチャを実装した技術”Miller は記事の終わりで、アプリを別々に届けられる部品に分けるための、すぐに使える道具が少ないと書き、“Who knows, maybe we can fix that.”(そこはなんとかできるかもしれない)と結んでいます。翌年から、その道具が現れます。
Astro の client:*(2021年〜)
Section titled “Astro の client:*(2021年〜)”Astro は2021年6月8日に発表されました(成り立ちは Astro の記事で扱います)。Astro のドキュメントによれば、Astro はページの部品を既定ではすべて HTML と CSS だけにし、ブラウザの JavaScript を送りません。動かしたい部品にだけ印を付けます。
2021年7月8日の 0.17.0 は、その印を <Button:load /> から <Button client:load /> の形に変え、変更記録に “Partial hydration is about to get super powers!”(部分的なハイドレーションに、これから強力な機能が加わる)と書きました。:idle と :visible も同じ形に揃い、8月18日の 0.19.0 では、サーバーで描かずにブラウザだけで描く client:only が加わります。
2026年10月時点のドキュメントにある主な印です。
| 印 | いつ動かすか |
|---|---|
client:load | ページを読み込んだらすぐ |
client:idle | ブラウザの手が空いたら |
client:visible | 部品が画面に入ったら |
client:media | メディアクエリに合ったら |
client:only | サーバーでは描かず、ブラウザでだけ描く |
Astro のドキュメントは、島を “an enhanced UI component on an otherwise static page of HTML”(ほかは静的な HTML のページの上にある、機能を足した UI の部品)と定義しています。React・Preact・Svelte・Vue・SolidJS の部品を島にでき、1つのページで混ぜることもできます。
コードで見る違い
Section titled “コードで見る違い”商品ページの説明は HTML のまま、カルーセル・購入ボタン・アンケートだけを動かしたい場合です。どれもこの記事のための作例で、部品のファイルや設定は省いています。
import { hydrateRoot } from 'react-dom/client';import { Carousel, BuyButton, Survey } from './components.jsx';
function ProductPage({ product }) { return ( <main> <h1>{product.name}</h1> <p>{product.description}</p> <Carousel images={product.images} /> <BuyButton id={product.id} /> <Survey /> </main> );}
const product = JSON.parse(document.getElementById('data').textContent);hydrateRoot(document.getElementById('app'), <ProductPage product={product} />);---import Carousel from '../components/Carousel.jsx';import BuyButton from '../components/BuyButton.jsx';import Survey from '../components/Survey.jsx';import product from '../data/product.json';---<main> <h1>{product.name}</h1> <p>{product.description}</p> <Carousel images={product.images} client:visible /> <BuyButton id={product.id} client:load /> <Survey client:idle /></main>React の例では、見出しと説明文もアプリの一部としてブラウザで処理され、そのためのデータも HTML に埋め込んで送ります。 Astro の例では、見出しと説明文は HTML だけで届き、ブラウザで動くのは印を付けた3つの部品だけです。 購入ボタンはすぐ、カルーセルは見えたとき、アンケートは手が空いたときと、Miller が書いた「どれを先に動かすか」の判断を、部品ごとの1語で書けます。
Fresh と <is-land>(2022年)
Section titled “Fresh と <is-land>(2022年)”2022年6月28日、Deno の Luca Casonato は Fresh 1.0 を発表しました。投稿は Miller の記事を引き、Fresh は既定でクライアントに “0 KB of JS”(0 KB の JavaScript)を送ると書いています。島にする部品は islands/ フォルダに置き、ページのテンプレートで使われていれば、Fresh がブラウザでハイドレーションします。Fresh のドキュメントによれば、島に渡す値は JSON にできる(シリアライズできる)ものでなければなりません。
その少し前の6月9日、Eleventy の Zach Leatherman は @11ty/is-land 1.0.0 を npm に公開し、翌10日に Eleventy の公式アカウントが “A framework-independent partial hydration islands architecture implementation.”(フレームワークに依存しない、部分的なハイドレーションによるアイランドアーキテクチャの実装)と紹介しました。
<is-land on:visible on:idle> のように HTML の要素で島を囲み、属性で動かす条件を書きます。README は、サーバーのフレームワークやサイトの生成ツールに縛られないことを特長に挙げています。
残した課題と、次に来たもの
Section titled “残した課題と、次に来たもの”島どうしで状態を共有したいときはどうするのか
Section titled “島どうしで状態を共有したいときはどうするのか”島は互いに切り離されて動きます。Miller の記事は、島どうしの状態の受け渡しには触れていません。 Astro のドキュメントは、島はいつもほかの島から切り離されて動くが、それでも状態を共有したり連絡し合ったりできる、と書いています。Fresh では、サーバーから島に渡す値は JSON にできるものに限られます。複数の島が同じ情報を使うなら、それをどこに置いてどう渡すかは、作る側が決めることになります。
Miller 自身も、この形は前もっての設計の検討を多く要するだろうと認めていました。「Rendering on the Web」も、部分的な再ハイドレーションには、キャッシュの扱いが難しくなることや、ブラウザの中で画面を移ると動かない部分の HTML が手元にあるとは限らないことといった問題があると書いています。 どこを島にするかと、島どうしをどうつなぐかを、作る側が決めなければなりません。
島より細かく、またはサーバーへ
Section titled “島より細かく、またはサーバーへ”島の考え方を広げる動きと、別の方向からの答えが続きました。
| 何を変えたか | |
|---|---|
| Astro の Server Islands(2024年) | 2024年7月18日の 4.12 で実験版として入り、12月3日の 5.0 で正式になった。server:defer を付けた部品はサーバーで別に描かれ、あとから差し込まれる。変更記録は、ページの残りをキャッシュしやすくし、静的に作ることもできると書く |
| React Server Components(2020年発表) | 2020年12月21日、React のチームがサーバーで動く部品として発表した。投稿は “still in research and development”(まだ研究開発の段階)と書いていた |
| Marko | 2026年10月時点の公式サイトは “Why ship entire Islands for a few grains of sand?”(砂粒いくつかのために、島をまるごと送る必要があるか)と書き、テンプレートの一部の単位でハイドレーションを省くとしている |
Astro のドキュメントは、ブラウザで動く島を client island、ログインした人のアイコンのようにサーバーで後から描く部品を server island と呼び分けています。
2026年10月時点の立ち位置
Section titled “2026年10月時点の立ち位置”2026年10月29日にパッケージの置き場で確かめた、島を看板にする主な実装の版です。
| 実装 | 2026年10月29日の版(公開日) | それまでの大きな版 |
|---|---|---|
| Astro(npm の astro) | 7.4.4(2026-10-28) | 6.0.0(2026-03-10)、7.0.0(2026-06-22) |
<is-land>(npm の @11ty/is-land) | 5.3.0(2026-10-28) | 5.0.0(2025-08-29) |
| Fresh(JSR の @fresh/core) | 2.3.3(2026-04-28) | 2.0.0(2025-09-09) |
Fresh は npm ではなく、Deno の JSR で配られています。npm にある「fresh」という名前のパッケージは、Deno の Fresh とは別物です。
Astro のドキュメントは、Astro が “the first mainstream JavaScript web framework with selective hydration built-in”(選択的なハイドレーションを組み込んだ、最初の主流の JavaScript の Web フレームワーク)として人気を得たと書いています。これは Astro 自身の評価です。 開発者への調査 State of JavaScript 2025 のメタフレームワークのページは、Astro が満足度で首位だったと書いています。
2026年10月時点で、アイランドは Astro・Fresh・<is-land> が実装する、現役の作り方です。 一方で、Astro 自身が Server Islands で島の意味をサーバー側に広げ、Marko は島より細かい単位を打ち出すなど、ページのどこにどれだけ JavaScript を送るかの答えは、いまも分かれています。
- 記事や商品説明が主のページでも、SPA のフレームワークはルートからページ全体をハイドレーションしていました。「Rendering on the Web」(2019年公開)は、一部だけをハイドレーションする手を挙げつつ、実装が難しいと書いています。
- 2020年8月11日、Jason Miller は、HTML はサーバーで描き、動く部分だけを島として別々にハイドレーションする考え方を書きました。名付けたのは2019年の Etsy の Katie Sylor-Miller だと、Miller 自身が記しています。
- jQuery のプラグインを当てる progressive enhancement と違い、島では同じ部品のコードが HTML と動きの両方を受け持ちます。Astro の
client:*(2021年)、Fresh と<is-land>(2022年)がこれを道具にしました。 - どこを島にするかの設計と、切り離された島どうしのつなぎ方が、作る側に残りました。Server Islands・React Server Components・Marko の細かい出し分けが、別の方向から答えています。
- 2026年10月時点で、Astro は 7.4.4、
<is-land>は 5.3.0、Fresh は 2.3.3 と、どれも更新が続いています。
年表
Google の「Rendering on the Web」が、ページの一部だけをハイドレーションする方法を挙げ、実装が難しいと書く web.dev
Jason Miller が「Islands Architecture」を書き、名付けたのは Etsy の Katie Sylor-Miller だと記す jasonformat.com
Fred Schott と Nate Moore が、部品ごとに JavaScript を送る Astro を発表する astro.build
Astro 0.17.0 が、部分的なハイドレーションの書き方を `<Button:load />` から `<Button client:load />` に変える raw.githubusercontent.com
Eleventy が、フレームワークに依存しない島の実装 `<is-land>` を「first-looks」として紹介する twitter.11ty.dev
Deno の Fresh 1.0 が、既定でクライアントに JavaScript を送らず、islands/ フォルダの部品だけを動かす形で安定版になる deno.com
Astro 1.0 が公開される astro.build
Astro 4.12 が、サーバー側の部品を後から差し込む Server Islands(`server:defer`)を実験版として入れる astro.build
Astro 5.0 で Server Islands が実験版でなくなる raw.githubusercontent.com
系譜
この技術が出てくる物語
同時代の出来事
- Google が Web Vitals(Core Web Vitals)を発表 blog.chromium.org
- Astro
出典
- 一次Islands Architecture(Jason Miller, 2020-08-11) jasonformat.com 保存版
- 一次Rendering on the Web(Addy Osmani・Jason Miller, web.dev, 2019-02-06 公開、2026-01-05 更新) web.dev 保存版
- 一次Islands architecture(Astro Docs) docs.astro.build
- 一次Template directives reference(Astro Docs) docs.astro.build
- 一次astro の CHANGELOG.md(0.19.0 のタグ。0.17.0 と 0.19.0 の項目) raw.githubusercontent.com
- 一次astro の CHANGELOG.md(5.0.0 のタグ) raw.githubusercontent.com
- 一次Introducing Astro: Ship Less JavaScript(Fred Schott・Nate Moore, Astro Blog, 2021-06-08) astro.build 保存版
- 一次Astro 1.0(Fred Schott, Astro Blog, 2022-08-09) astro.build
- 一次Astro 4.12(Astro Blog, 2024-07-18) astro.build
- 一次Fresh 1.0(Luca Casonato, Deno Blog, 2022-06-28) deno.com
- 一次Islands(Fresh のドキュメント) usefresh.dev
- 一次JSR @fresh/core の版の一覧 jsr.io
- 一次Eleventy の投稿「Ready for first-looks: <is-land>」(2022-06-10) twitter.11ty.dev
- 一次11ty/is-land の README github.com
- 一次npm registry(@11ty/is-land) registry.npmjs.org
- 一次Marko(公式サイトのトップ) markojs.com
- 一次Introducing Zero-Bundle-Size React Server Components(React Blog, 2020-12-21) react.dev
- 一次State of JavaScript 2025「Meta-Frameworks」 2025.stateofjs.com