アイランドアーキテクチャ
Astroはアイランドアーキテクチャと呼ばれる新しいフロントエンドアーキテクチャパターンを提唱し、普及させました。アイランドアーキテクチャでは、ページの大部分を高速な静的HTMLとしてレンダリングし、インタラクティブ性やパーソナライズが必要な箇所に小さなJavaScriptの”アイランド”を追加します(たとえば、画像カルーセルなど)。これにより、多くのモダンJavaScriptフレームワークで問題となる巨大なJavaScriptペイロードによるレスポンス低下を防げます。
簡単な歴史
セクションタイトル: 簡単な歴史”コンポーネントアイランド”という用語は、2019年にEtsyのフロントエンドアーキテクトKatie Sylor-Miller氏が初めて提案しました。その後、Preactの創始者Jason Miller氏が2020年8月11日の記事で概念を拡張し、体系立てて紹介しました。
「Islands」アーキテクチャの基本的な考え方は一見単純です。サーバーでHTMLページをレンダリングし、高度に動的な領域をプレースホルダーやスロットで囲み、クライアント側でそれらを小さな自己完結型ウィジェットへと“ハイドレート”して、サーバーレンダリング済みの初期HTMLを再利用するのです。
— Jason Miller(Preact創始者)
このアーキテクチャパターンが基礎とする技術は、パーシャルハイドレーションまたはセレクティブハイドレーションとも呼ばれます。
対照的に、多くのJavaScriptベースのウェブフレームワークは、ウェブサイト全体を巨大なJavaScriptアプリケーション(シングルページアプリケーション、SPA)としてハイドレートし、レンダリングします。SPAはシンプルかつ強力ですが、大量のクライアントサイドJavaScriptのためにページロード性能が低下しがちです。
SPAは、Astroページ内に埋め込む (EN)場合など適切な用途があります。しかし、SPAには選択的かつ戦略的にハイドレートするネイティブ機能がないため、今日の多くのプロジェクトにとっては過剰な選択肢となることが少なくありません。
Astroは、Sylor-Miller氏が提唱したコンポーネントアイランドパターンを内蔵した最初の主流JavaScriptウェブフレームワークとして人気を博しました。それ以来、私たちはSylor-Miller氏の原案を拡張、発展させ、動的なサーバーレンダリングコンテンツにも応用できる類似のコンポーネントアイランド手法へと進化させています。
アイランドとは
セクションタイトル: アイランドとはAstroでは、アイランドとは静的なHTMLページ上に存在する拡張UIコンポーネントです。
クライアントアイランドはページ全体とは独立してハイドレーションされるインタラクティブなJavaScript UIコンポーネントであり、サーバーアイランドはページとは別に動的コンテンツをサーバーレンダリングするUIコンポーネントです。
どちらのアイランドもコンポーネント単位で高コストまたは時間のかかる処理を個別に実行し、ページロードを最適化します。
アイランドコンポーネント
セクションタイトル: アイランドコンポーネントAstroコンポーネントはページテンプレートの構成要素で、クライアントサイドのランタイムなしに静的HTMLへレンダリングされます。
クライアントアイランドは、静的で軽量、かつサーバーレンダリングされたHTMLの海に浮かぶインタラクティブウィジェットのようなものです。サーバーアイランドを追加すれば、ログイン中の訪問者のプロフィール画像など、パーソナライズされた動的要素をサーバーレンダリングできます。
テキストや画像などの静的コンテンツ
出典: Islands Architecture: Jason Miller
アイランドは常にページ上の他のアイランドから独立して実行され、複数のアイランドを同一ページに配置できます。コンポーネントコンテキストが異なっていても、クライアントアイランド同士は状態を共有し、相互通信が可能です。
この柔軟性により、AstroはReact、Preact、Svelte、Vue、SolidJSなど複数のUIフレームワークをサポートします。アイランドは独立しているため、1ページ内で複数フレームワークを混在させることもできます。
ほとんどの開発者は1つのUIフレームワークに絞りますが、Astroでは同一プロジェクト内で複数フレームワークを利用できます。これにより次のことが可能です。
- コンポーネントごとに最適なフレームワークを選択する
- 新しいプロジェクトを始めなくても新しいフレームワークを学習できる
- 異なるフレームワークで開発していても共同作業できる
- 既存サイトをダウンタイムなしで段階的に別フレームワークへ移行できる
クライアントアイランド
セクションタイトル: クライアントアイランドデフォルトでは、AstroはすべてのUIコンポーネントをHTMLとCSSのみへレンダリングし、クライアントサイドJavaScriptを自動的に取り除きます。
<MyReactComponent />
一見厳しいように思えるかもしれませんが、この挙動こそがAstroサイトをデフォルトで高速に保ち、開発者が不要なJavaScriptを誤って送信してサイトを遅くしてしまうことを防ぎます。
静的UIコンポーネントをインタラクティブなアイランドに変えるには、client:*
ディレクティブを付与するだけです。Astroは最適化されたパフォーマンスのためにクライアントサイドJavaScriptを自動的にビルド、バンドルします。
<!-- このコンポーネントはページ上でインタラクティブになりました。サイトの残り部分は静的のままです。 --><MyReactComponent client:load />
アイランドを使用すると、クライアントサイドJavaScriptはclient:*
ディレクティブで明示的に指定したインタラクティブコンポーネントに対してのみ読み込まれます。
また、インタラクションをコンポーネント単位で設定できるため、使用状況に応じて各コンポーネントの読み込み優先度を細かく制御できます。たとえばclient:idle
はブラウザがアイドル状態のときにコンポーネントを読み込み、client:visible
はビューポートに入ったときにのみ読み込みます。
クライアントアイランドの利点
Astroアイランドの最大の利点はパフォーマンスです。サイトの大部分が高速な静的HTMLになり、JavaScriptは必要なコンポーネントに対してのみ読み込まれます。JavaScriptはバイトあたりで最も遅いアセットのひとつなので、1バイトでも削減が重要です。
もうひとつの利点は並列読み込みです。上図の例では、低優先度の「画像カルーセル」アイランドが高優先度の”ヘッダー”アイランドをブロックしません。両者は並列に読み込まれ、独立してハイドレーションされるため、ヘッダーはページ下部の重いカルーセルを待たずにすぐにインタラクティブになります。
さらに、各コンポーネントをいつどのようにレンダリングするかをAstroに正確に指示できます。たとえば画像カルーセルのロードコストが高い場合は、クライアントディレクティブを使用してカルーセルがページ内で可視になったときだけ読み込むようにAstroに指示できます。ユーザーがカルーセルを一度も見なければロードされることはありません。
Astroでは、どのコンポーネントがブラウザ上でも実行される必要があるかを開発者が明示的に指定します。Astroは必要な部分だけをハイドレーションし、残りのサイトは静的HTMLのままにします。
クライアントアイランドこそが、Astroの”デフォルトで高速”なパフォーマンスを支える秘密です!
サーバーアイランド
セクションタイトル: サーバーアイランドサーバーアイランドは、コストの高いサーバーサイドコードや処理時間の長いコードをメインレンダリングから切り離し、高速な静的HTMLと動的サーバー生成コンポーネントを簡単に組み合わせる仕組みです。
ページ上の任意のAstroコンポーネントにserver:defer
ディレクティブを追加すると、そのコンポーネントは独立したサーバーアイランドになります。
---import Avatar from "../components/Avatar.astro";---<Avatar server:defer />
これにより、ページは複数のサーバーレンダリング領域へ分割され、それぞれが並列に読み込まれます。
アイランド独自のコンテンツが用意できるまで、汎用アバターなどのプレースホルダーを表示しつつ、ページ本体を即座にレンダリングできます。サーバーアイランドを使えば、パーソナライズ要素があっても静的ページ全体の描画を遅らせません。
このレンダリングパターンは移植性を考慮して設計されており、特定のサーバーインフラに依存しないため、Node.jsサーバー(Dockerコンテナ内)から任意のサーバーレスプロバイダーまで、あらゆるホストで動作します。
サーバーアイランドの利点
一つ目として動的領域のオンザフライ描画があります。ページ外枠やメインコンテンツをより攻めたキャッシュ戦略で配信しつつ、動的部分だけをその場でレンダリングできます。
二つ目として優れたユーザー体験があります。サーバーアイランドは最適化済みで高速に読み込まれ、ブラウザがページをペイントする前に完了することも多いです。アイランド描画に短時間かかる場合も、カスタムフォールバックコンテンツを表示してレイアウトシフトを防げます。
Astroのサーバーアイランドが役立つ好例として、ECサイトのストアフロントがあります。商品ページのメインコンテンツは更新頻度が低い一方、次のような動的要素を含むことが一般的です。
- ヘッダー内のユーザーアバター
- 商品の特別割引やセール情報
- ユーザーレビュー
これら要素をサーバーアイランド化すれば、訪問者は最重要コンテンツである商品を即座に閲覧できます。パーソナライズ部分が準備できるまで、汎用アバターやローディングスピナー、ストアのお知らせをフォールバックとして表示できます。