liliya.dev

Astroを使って個人サイトを作ってみた

公開日時:2024/04/04

まえがき

この度、個人サイトをAstro + microCMS + Vercelを使って作成しました。
この記事ではAstroの特徴と使用した所感を記述します。

Astroの特徴

Astroはコンテンツにフォーカスした高速なwebサイトを構築するためのフレームワークであり、可能な限りJavaScriptを取り除きます。そのため静的サイトの構築に特化したものになります。

AstroはSSG(静的サイトジェネレーター)で生成して、MPA(マルチページアプリケーション)でレンダリングします。そして、Astro Islandによりコンポーネントが独立しているため、コンポーネントごとに好きなフレームワークを活用してサイトの構築を行うことができます。

Astroコンポーネント

Astroコンポーネントはデフォルトでは、ビルド後にJavascriptは実行されるのでクライアントサイドの処理を持たないHTMLが生成されます。そのためインタラクティブなコンポーネントを扱うためにはclient:*、ハイドレーションディレクティブをコンポーネントに設定する必要があります。ハイドレーションディレクティブの種類については後述します。

アイランドアーキテクチャ

Astroを活用する上で重要になってくるのはアイランドアーキテクチャです。 ここにおけるアイランドはページ上のインタラクティブなUIコンポーネントのことを指します。 "アイランド = 島" "ページ = 海" のようなイメージです。

インタラクティブなコンポーネントとはユーザーが操作するような ハンバーガーメニューやダークモードのボタン等のコンポーネントを指します。 このようなコンポーネントごとにJavascriptをロードしてハイドレーションすることをPartial Hydrationと言います。

ハイドレーションの種類

前提として、ハイドレーションにはコンポーネントがいつロードされるかの優先度があります。デフォルトでは同じ優先度でハイドレーションされます。

client:load

優先度:高
できるだけはやくインタラクティブにする必要があるコンポーネントに設定する。ページの読み込み時にコンポーネントJavascriptを読み込んでハイドレーションをします。


   <BuyButton client:load/>

client:idle

優先度:中
すぐにインタラティブにする必要がない、優先順位の低いコンポーネントに設定する。初期ロード完了後にイベントが発生したら、コンポーネントJavascriptをロードしてハイドレーションをします。


   <BuyButton client:idle/>

client:visible

優先度:低
スクロールしないと見えない部分の優先度の低いJavascriptコンポーネントをロードしてハイドレーションをします。


   <BuyButton client:visible/>

client:visible={{rootMargin}}

rootMargingを渡しコンポーネント自体ではなく周りの指定されたマージンがビューポートに入った時にハイドレーションされます。値を設定をするとCLS対策にもなります。


   <BuyButton client:visible={{rootMargin}}/>

client:media

優先度:低
使い方:特定の画面サイズでのみ表示される要素に対して設定をします。


   <BuyButton client:media/>

client:only

SSRをスキップし、CSRのみにします。ページの読み込み時にすぐにコンポーネントを読み込み、レンダリングをします。注意点としてはどのフレームワーク・ライブラリを使ったかを明示する必要があります。


   <BuyButton client:only/>

利用できるフレームワーク/ライブラリの種類

React , Preact , Svelte , Vue , SolidJS , AlpineJS , Lit等のフレームワーク/ライブラリをサポートしています。

前節から、Astroではクライアント側で使用するJavascriptがなければ静的なHTMLとして出力することがわかりましたが、Javascriptを使用した場合どのように出力されるか気になったので調べてみました。

出力結果を検証する

出力結果を検証するために、Reactを使った処理とJavascriptを使った処理を作りました。


/* jsx */
export const Button = () => {
  const buttonClick = () => {
    alert('Hello, World!');
  };
  return (
    <button onClick={buttonClick}>ボタン</button>
  );
};


/* javascript*/
 document.getElementById("button")?.addEventListener("click", () => {
    alert("Hello.World");
 });

上記をビルドすると下記のようになりました。Javascriptのコードはモジュール化され、Jsxはminifi化されました。さらに_astroフォルダの中にJavascriptファイルが生成されました。

vscodeのコード画面

所感

結論から言うととても良かったです。プロジェクトを立ち上げるのも簡単で、日本語のドキュメントも豊富なので学習コストは低いと感じます。さらに、さまざまなフレームワーク・ライブラリに対応しているので複雑なUIの作成もでき、コンポーネントによって保守性を高めることもできるのでゆくゆくは実務にも組み込んでいければと思いました。

参考