mcpField
I
islands-architecture

islands-architecture

github.com/patternsdev開発257625 回インストール28 週間前に更新
リポジトリ

islands-architecture について

静的コンテンツ中心のサイトを構築する開発者向けに、アイランドアーキテクチャを解説します。HTMLを静的に保ち、独立したインタラクティブコンポーネントだけを読み込んでハイドレーションする手法で、初期表示やSEOを重視するページに適しています。

主な機能

  1. 01静的領域と操作領域を分離
  2. 02独立した操作コンポーネントをハイドレーション
  3. 03クライアントに送るJavaScriptを削減
  4. 04静的レンダリングでSEOに対応
  5. 05AstroやMarkoなどの実装例を紹介

活用シーン

  1. 01ブログ記事にソーシャルボタンを追加
  2. 02商品ページに画像カルーセルを埋め込む
  3. 03静的な取引一覧にフィルターを追加

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/patternsdev/skills --skill islands-architecture

インストール後、Claude Code で/islands-architectureを入力して読み込まれたか確認します。

詳細

Islands アーキテクチャ

目次

使用する場面

  • インタラクティブな要素を少しだけ追加したい、主に静的なウェブサイト(ブログ、製品ページ、ニュースサイト)に使用します
  • クライアントに送信する JavaScript の量を減らしたい場合に役立ちます
  • SEO と初回ページ読み込みの速さを優先しつつ、一部だけをインタラクティブにしたい場合に使用します

手順

  • 各ページの静的領域と動的領域を個別に特定します
  • Islands アーキテクチャに対応する Astro、Marko、Eleventy などのフレームワークを使用します
  • client:visible などのディレクティブを使用して、インタラクティブなコンポーネントを個別にハイドレーションします
  • ページの大部分を、JavaScript の負荷がまったくない静的 HTML のままにします

詳細

過剰な JavaScript の読み込みと処理は、パフォーマンスを損なう可能性があります。しかし、主に静的なウェブサイトであっても、ある程度のインタラクティブ性と JavaScript が必要になることはよくあります。これまで、次のバランスを取ろうとするアプリケーションを構築できる、静的レンダリングのさまざまな手法について説明してきました。

  1. クライアントサイドレンダリング(CSR)アプリケーションに匹敵するインタラクティブ性
  2. SSR アプリケーションに匹敵する SEO 上の利点

SSR の基本原則は、サーバー上で HTML をレンダリングし、クライアント上で再ハイドレーションするために必要な JavaScript とともに送信することです。再ハイドレーションとは、サーバーが UI コンポーネントをレンダリングした後、クライアント側でその状態を再生成するプロセスです。再ハイドレーションにはコストがかかるため、SSR の各手法では再ハイドレーションのプロセスを最適化しようとします。これは主に、重要なコンポーネントを部分的にハイドレーションするか、コンポーネントがレンダリングされるたびにストリーミングすることで実現します。しかし、上記の手法では、最終的に送信される JavaScript の総量は変わりません。

Islands アーキテクチャという用語は、Katie Sylor-Miller と Jason Miller によって広められました。この用語は、静的 HTML の上に独立して配信できるインタラクティブな「アイランド」を通じて、送信する JavaScript の量を減らすことを目指すパラダイムを表しています。Islands はコンポーネントベースのアーキテクチャであり、ページを静的なアイランドと動的なアイランドに区分して捉えることを提案します。ページの静的領域は、インタラクティブ性のない純粋な HTML であり、ハイドレーションは不要です。動的領域は、レンダリング後に自身を再ハイドレーションできる HTML とスクリプトの組み合わせです。

動的コンポーネントのアイランド

ほとんどのページは、静的コンテンツと動的コンテンツを組み合わせたものです。通常、ページは静的コンテンツを中心に、切り分け可能なインタラクティブ領域が点在する構成です。たとえば、次のようなものがあります。

  1. ブログ記事、ニュース記事、組織のホームページには、ソーシャルメディアの埋め込みやチャットなどのインタラクティブなコンポーネントとともに、テキストや画像が含まれています。
  2. Eコマースサイトの商品ページには、静的な商品説明と、アプリ内の他のページへのリンクが含まれています。画像カルーセルや検索などのインタラクティブなコンポーネントは、ページ内のさまざまな領域で利用できます。
  3. 一般的な銀行口座の詳細ページには、静的な取引履歴の一覧があり、フィルターによって一部の操作が可能になっています。

静的コンテンツはステートレスで、イベントを発生させず、レンダリング後の再ハイドレーションも必要ありません。レンダリング後、動的コンテンツ(ボタン、フィルター、検索バー)はイベントに再接続する必要があります。クライアント側ではDOMを再生成する必要があります(仮想DOM)。この再生成、再ハイドレーション、イベント処理の機能が、クライアントに送信されるJavaScriptに含まれます。

Islandsアーキテクチャでは、ページのすべての静的コンテンツをサーバー側でレンダリングできます。ただし、この場合、レンダリングされたHTMLには動的コンテンツ用のプレースホルダーが含まれます。動的コンテンツのプレースホルダーには、自己完結型のコンポーネントウィジェットが含まれています。各ウィジェットはアプリに似ており、サーバーでレンダリングされた出力と、クライアントでアプリをハイドレーションするためのJavaScriptを組み合わせています。

プログレッシブ・ハイドレーションでは、ページのハイドレーションアーキテクチャはトップダウンです。ページが、個々のコンポーネントのスケジュール設定とハイドレーションを制御します。Islandsアーキテクチャでは、各コンポーネントが独自のハイドレーションスクリプトを持ち、ページ上の他のスクリプトとは独立して非同期に実行されます。あるコンポーネントのパフォーマンス問題が、他のコンポーネントに影響することはありません。

Islandsの実装

Islandアーキテクチャはさまざまなソースの概念を取り入れ、それらを最適に組み合わせることを目指しています。JekyllやHugoなどのテンプレートベースの静的サイトジェネレーターは、ページへの静的コンポーネントのレンダリングをサポートしています。最新のJavaScriptフレームワークの多くもアイソモーフィックレンダリングをサポートしており、サーバーとクライアントで同じコードを使って要素をレンダリングできます。

Jasonの投稿では、コンポーネントのハイドレーションにスケジューリング方式を実装するために、requestIdleCallback()を使用することを提案しています。静的なアイソモーフィックレンダリングと、コンポーネント単位の部分的なハイドレーションのスケジューリングをフレームワークに組み込むことで、Islandsアーキテクチャをサポートできます。したがって、フレームワークには次の機能が必要です。

  1. JavaScriptを一切使わずに、ページをサーバー上で静的にレンダリングできること。
  2. 静的コンテンツ内のプレースホルダーを介して、独立した動的コンポーネントを埋め込めること。各動的コンポーネントは独自のスクリプトを持ち、メインスレッドが空き次第、requestIdleCallback()を使って自身をハイドレーションできます。
  3. サーバー上でコンポーネントをアイソモーフィックにレンダリングし、クライアントでハイドレーションを行うことで、両方の環境で同じコンポーネントを認識できること。
フレームワーク

現在、さまざまなフレームワークが Islands アーキテクチャをサポートしています。代表的なものは次のとおりです。

  1. Marko:Marko は、サーバー側のレンダリング性能を向上させるために eBay が開発し、保守しているオープンソースのフレームワークです。ストリーミングレンダリングと自動的な部分ハイドレーションを組み合わせることで、Islands アーキテクチャをサポートしています。HTML やその他の静的アセットは、準備ができ次第クライアントにストリーミングされます。自動的な部分ハイドレーションにより、インタラクティブなコンポーネントは自らハイドレーションできます。ハイドレーションコードは、ブラウザー上で状態を変更できるインタラクティブなコンポーネントにのみ配信されます。Marko はアイソモーフィックであり、Marko コンパイラーは実行場所(クライアントまたはサーバー)に応じて最適化されたコードを生成します。

  2. Astro:Astro は、React、Preact、Svelte、Vue などの他のフレームワークで構築された UI コンポーネントから、軽量な静的 HTML ページを生成できる静的サイトビルダーです。クライアント側の JavaScript が必要なコンポーネントは、それぞれの依存関係とともに個別に読み込まれます。そのため、部分ハイドレーションが組み込みでサポートされています。また、コンポーネントが表示されるタイミングに応じて、Astro はコンポーネントを遅延読み込みできます。

  3. Eleventy + Preact:Markus Oberlehner は、部分ハイドレーションが可能なアイソモーフィック Preact コンポーネントを備えた静的サイトジェネレーター、Eleventy の使用例を紹介しています。遅延ハイドレーションにも対応しています。コンポーネント自体が宣言的にそのハイドレーションを制御します。インタラクティブなコンポーネントでは WithHydration ラッパーを使用し、クライアント上でハイドレーションします。

Marko と Eleventy は、Jason が Islands を定義するよりも前から存在していましたが、Islands のサポートに必要な機能の一部を備えています。一方、Astro はこの定義に基づいて構築されており、Islands アーキテクチャを標準でサポートしています。

実装例

以下は Astro で実装されたブログページの例です。ページ SamplePost は、インタラクティブなコンポーネント SocialButtons を 1 つインポートします。このコンポーネントはマークアップによって、必要な位置に HTML として含められます。

// Component Imports
import { SocialButtons } from '../../components/SocialButtons.js';

<html lang="en">
 <head>
   <link rel="stylesheet" href="/blog.css" />
 </head>

 <body>
   <div class="layout">
     <article class="content">
       <section class="intro">
         <h1 class="title">Post title (static)</h1>
         <br/>
         <p>Post sub-title (static)</p>
       </section>
       <section class="intro">
           <p>This is the post content with images that is rendered by the server.</p>
           <p>The next section contains the interactive social buttons component which includes its script.</p>
       </section>
       <section class="social">
           <div>
           <SocialButtons client:visible></SocialButtons>
           </div>
       </section>
     </article>
   </div>
 </body>
</html>
// SocialButtons.js
import { useState } from "preact/hooks";

export function SocialButtons() {
  const [count, setCount] = useState(0);
  const add = () => setCount((i) => i + 1);
  const subtract = () => setCount((i) => i - 1);
  return (
    <>
      <div>{count} people liked this post</div>
      <div align="right">
        <button onclick={add}>Like</button>
        <button onclick={subtract}>Unlike</button>
      </div>
    </>
  );
}

SocialButtons コンポーネントは Preact コンポーネントであり、HTML と対応するイベントハンドラーが含まれています。

このコンポーネントは実行時にページに埋め込まれ、必要なとおりにクリックイベントが機能するよう、クライアント側でハイドレーションされます。

Astro では HTML、CSS、スクリプトを明確に分離でき、コンポーネントベースの設計が推奨されています。このフレームワークは簡単にインストールでき、すぐに Web サイトの構築を始められます。

メリットとデメリット

Islands アーキテクチャは、サーバーサイドレンダリング、静的サイト生成、部分的なハイドレーションなど、さまざまなレンダリング手法の考え方を組み合わせたものです。Islands を導入することで得られるメリットには、次のようなものがあります。

  1. パフォーマンス:クライアントに送信する JavaScript コードの量を削減できます。送信されるコードはインタラクティブなコンポーネントに必要なスクリプトだけなので、ページ全体の仮想 DOM を再作成し、ページ上のすべての要素を再ハイドレーションするために必要なスクリプトよりも大幅に少なくなります。JavaScript のサイズが小さくなることで、ページの読み込みが速くなり、インタラクティブになるまでの時間(TTI)も短縮されます。

  2. **SEO:**静的コンテンツはすべてサーバーでレンダリングされるため、ページは SEO に適しています。

  3. 重要なコンテンツを優先:主要なコンテンツ(特にブログ、ニュース記事、製品ページ)は、ほぼすぐにユーザーに表示されます。インタラクティブ機能を提供する二次的な機能は、通常、主要なコンテンツを消費した後に必要となるため、徐々に利用可能になります。

  4. アクセシビリティ:ほかのページへのアクセスに標準的な静的 HTML リンクを使用することで、ウェブサイトのアクセシビリティを向上させられます。

  5. コンポーネントベース:このアーキテクチャには、再利用性や保守性など、コンポーネントベースのアーキテクチャがもたらすすべての利点があります。

メリットがある一方で、この概念はまだ初期段階にあります。サポートが限られているため、いくつかのデメリットもあります。

  1. Islands を実装するために開発者が利用できる選択肢は、数少ないフレームワークのいずれかを使うか、アーキテクチャを自分で開発することだけです。既存のサイトを Astro や Marko に移行するには、追加の作業が必要になります。
  2. Jason による最初の投稿以外には、このアイデアに関する議論はほとんどありません。
  3. Islands アーキテクチャをサポートすると主張する新しいフレームワークが登場しており、自分に適したものを見極めるのが難しくなっています。
  4. このアーキテクチャは、ソーシャルメディアアプリのような高度にインタラクティブなページには適していません。そのようなページでは、おそらく数千ものアイランドが必要になります。

Islands アーキテクチャの概念は比較的新しいものですが、パフォーマンス上の利点から、今後普及していく可能性があります。このアーキテクチャは、パフォーマンスへの影響を最小限に抑えながら、動的なコンポーネントでインタラクティブ性を実現しつつ、静的コンテンツのレンダリングには SSR を使うことを重視しています。今後、この分野にさらに多くのプレイヤーが参入し、実装方法の選択肢が広がることを期待しています。

ソース

参考資料

コメント