コンテンツにスキップ

サーバーアイランド

サーバーアイランドは、ページ全体のパフォーマンスを犠牲にせず、動的またはパーソナライズされた”アイランド”を個別にオンデマンドでレンダリングできます。

これにより、訪問者はページの最重要部分をより早く表示でき、メインコンテンツはより積極的にキャッシュできるため、パフォーマンスが向上します。

サーバーアイランドは、通常のサーバーレンダリングされたAstroコンポーネントであり、そのコンテンツが利用可能になるまでレンダリングを遅延させるよう指示されます。

ページは、プレースホルダーとして指定されたフォールバックコンテンツを含め、すぐにレンダリングされます。その後、コンポーネント独自のコンテンツがクライアント側で取得され、利用可能になった時点で表示されます。

インストール済みのアダプターで遅延レンダリングを実行する場合、ページ内の任意のコンポーネントにserver:deferディレクティブを追加すると、そのコンポーネントを独立したアイランドにできます。

src/pages/index.astro
---
import Avatar from '../components/Avatar.astro';
---
<Avatar server:defer />

これらのコンポーネントは、アダプターを使用することで、コンテンツの取得やCookieへのアクセスなど、オンデマンドレンダリングページで通常行えることがすべて可能です。

src/components/Avatar.astro
---
import { getUserAvatar } from '../sessions';
const userSession = Astro.cookies.get('session');
const avatarURL = await getUserAvatar(userSession);
---
<img alt="User avatar" src={avatarURL} />

サーバーアイランドのフォールバックコンテンツ

セクションタイトル: サーバーアイランドのフォールバックコンテンツ

server:defer属性を使ってコンポーネントのレンダリングを遅延させる場合、組み込みの"fallback"という名前のスロットを使って、デフォルトの読み込みコンテンツを”スロット挿入”できます。

フォールバックコンテンツは、ページ読み込み時に他のコンテンツと一緒にレンダリングされ、コンポーネントのコンテンツが利用可能になったときに置き換えられます。

フォールバックコンテンツを追加するには、サーバーアイランドコンポーネントに渡す子コンポーネントやHTML要素にslot="fallback"を指定します。

---
import Avatar from '../components/Avatar.astro';
import GenericAvatar from '../components/GenericAvatar.astro';
---
<Avatar server:defer>
<GenericAvatar slot="fallback" />
</Avatar>

フォールバックコンテンツの例は次の通りです。

  • ユーザー固有のアバターの代わりの汎用アバター
  • カスタムメッセージなどのプレースホルダーUI
  • スピナーなどの読み込みインジケーター

サーバーアイランドの実装は、主にビルド時に行われ、コンポーネントのコンテンツが小さなスクリプトに置き換えられます。

server:deferが付いた各アイランドは、専用の特別なルートに分割され、実行時にスクリプトが取得します。Astroがサイトをビルドすると、コンポーネントは省略され、代わりにスクリプトとslot="fallback"でマークされたコンテンツが注入されます。

ブラウザでページが読み込まれると、これらのコンポーネントは特別なエンドポイントにリクエストされ、HTMLが返されます。このため、ユーザーはページの最重要部分を即座に表示できます。フォールバックコンテンツは短時間表示され、その後、動的アイランドが読み込まれます。

各アイランドは他と独立してロードされます。つまり、遅いアイランドがあっても、他のパーソナライズされたコンテンツの表示を遅らせることはありません。

このレンダリングパターンは、あらゆるホスティング環境で動作するように設計されています。Node.jsサーバー(Dockerコンテナ内)から任意のサーバーレスプロバイダーまで、サーバーインフラに依存しません。

サーバーアイランドのデータは、URLクエリ内の暗号化された文字列としてpropsを渡すGETリクエストで取得されます。これにより、標準のCache-ControlHTTPヘッダーを使用して、Cache-Controlディレクティブによるデータキャッシュが可能です。

ただし、ブラウザにはURL長の実用的な上限(2048バイト)が存在します。この制限を超えると、Astroは代わりにprops全体を本文に含めたPOSTリクエストを送信します。

POSTリクエストはデータ送信用に使われ、データの完全性やセキュリティ上の理由からブラウザによってキャッシュされません。そのため、プロジェクト内の既存のキャッシュロジックは動作しなくなります。可能な限り、必要最小限のpropsのみをサーバーアイランドに渡し、クエリサイズを小さく保つようにしてください。

サーバーアイランド内でページURLにアクセスする

セクションタイトル: サーバーアイランド内でページURLにアクセスする

通常、サーバーアイランドコンポーネントは、他のコンポーネントと同じようにpropsを渡すことで、レンダリングするページに関する情報を取得できます。

しかし、サーバーアイランドはページリクエストの外側にある独立したコンテキストで実行されます。そのため、サーバーアイランドコンポーネント内でのAstro.urlAstro.request.urlは、現在のブラウザのページURLではなく、/_server-islands/AvatarのようなURLを返します。さらに、ページをプリレンダリングしている場合、クエリパラメーターなどの情報にアクセスできないため、propsとして渡せません。

ページURLの情報を取得するには、Refererヘッダーを確認できます。これには、ブラウザでアイランドを読み込んでいるページのアドレスが含まれています。

---
const referer = Astro.request.headers.get('Referer');
const url = new URL(referer);
const productId = url.searchParams.get('product');
---

Astroは、propsが秘密情報を誤って漏洩しないよう、サーバーアイランドに渡すpropsを暗号化します。この暗号化は、ビルド時に生成されたキーを使って行われます。

ほとんどのホスティング環境では、これは透過的に処理され、開発者が特別な対応をする必要はありません。しかし、Kubernetesのようなローリングデプロイ環境では、フロントエンドとバックエンドが一時的に同期せず、キーが一致しない問題が発生する可能性があります。

これを解決するには、Astro CLIでキーを作成し、それをすべてのデプロイで再利用します。これにより、各ユーザーのフロントエンドが正しいキーを持つバックエンドと通信できるようになります。

astro create-keyを使ってキーを生成します。

ターミナルウィンドウ
astro create-key

これにより、ホスティング環境で必要な場所(たとえば.envファイル)に設定できるキーが作成されます。

.env
ASTRO_KEY=zyM5c0qec+1Sgi4K+AejFX9ufbig7/7wIZjxOjti9Po=
貢献する コミュニティ スポンサー