技術記事の本文は、読者がスクロールして文章や表を読む時間がほとんどを占める。 そこへ最初からUIフレームワークと状態管理を載せると、実装は統一しやすく見える一方、ブラウザで実行する理由のないJavaScriptまで抱え込みやすい。
このサイトではAstro 7を土台にして、PreactとSignalsはまだインストールしていない。 その判断が単なる設計方針で終わらず、production buildでも記事ページから実行用JavaScriptを外せているかを確認した。
Astroが静的HTMLを既定にする仕組み
Astroのクライアントアイランドは、静的なページの一部だけをブラウザで動かす仕組みである。
Astroの公式ドキュメントでは、通常のUIコンポーネントは既定でHTMLとCSSへレンダリングされ、クライアント側で動かすコンポーネントだけにclient:*ディレクティブを付ける設計になっている。
したがって、記事本文、ヘッダー、フッター、記事カードのように表示だけで成立する部分へ、React系のランタイムを配信する必要はない。 一方、検索結果を入力に応じて即時に絞り込むUIや、ベンチマーク表を複数条件で切り替えるUIには、ブラウザ側の状態が必要になる。
この境界をコンポーネント単位で保てる点が、記事サイトでAstroを使う理由になる。
Tailwind CSS 4はViteのビルド工程に置く
Tailwind CSS 4は@tailwindcss/viteを使ってAstroのViteパイプラインへ組み込んだ。
Tailwind CSSのVite向け手順も、Viteプラグインを追加してCSSから@import "tailwindcss"を読み込む構成を示している。
ここでTailwindを使う目的は、ブラウザに別のJavaScriptランタイムを足すことではない。 必要なCSSをビルド時に生成し、サイト固有のタイポグラフィや配色は小さなデザイントークンとしてCSS側に残す。
このサイトでは汎用コンポーネントライブラリも入れていない。 記事カードやナビゲーション程度なら、AstroコンポーネントとCSSだけの方が依存関係と出力を追いやすいからだ。
検証条件
検証対象は、このサイト自身のproduction buildである。 2026年8月20日時点の環境は次の通りだった。
| 項目 | バージョン |
|---|---|
| Node.js | 26.7.0 |
| Astro | 7.2.4 |
| Tailwind CSS | 4.3.3 |
| pnpm | 11.9.0 |
記事ページにはclient:*ディレクティブを置かず、Preact、React、Solid、Svelteも依存関係へ追加していない。
構造化データ用のapplication/ld+jsonはscript要素になるが、ブラウザでアプリケーションコードとして実行するJavaScriptとは分けて数える。
再現手順はproduction buildを実行するだけである。
pnpm build
pnpm buildはAstroのproduction build後にreport-build.mjsを実行する。
スクリプトはdistを走査し、生成ファイル数とサイズを集計したうえで、この記事のHTMLに含まれるscript要素を分類する。
外部の実行用JavaScriptが一つでも見つかった場合は、スクリプト自体を失敗させる。
測定では、production outputにJavaScriptファイルは生成されなかった。
この記事のHTMLにも実行可能なscript要素は0件だった。
| 測定対象 | 結果 |
|---|---|
| 生成されたJavaScriptファイル | 0 |
| Zodを含むclient chunk | 0 |
記事HTMLの実行可能なscript要素 |
0 |
| CSSファイル | 1 |
| CSSサイズ | 12,579 bytes |
| CSSの個別gzip換算 | 3,848 bytes |
Astro Content Collectionsのfrontmatter検証には、Astro標準のastro/zodをビルド時だけ使用している。
Zodをブラウザ側のvalidatorとして採用したわけではなく、今回の生成物検査でもZodを含むclient chunkは0件だった。
将来ブラウザ側で入力検証が必要になった場合は、静的記事へ影響させないIsland内に限定し、Valibotのような小さなruntime validatorを候補にする。
この値は「Astroなら常にJavaScriptが0になる」という一般則ではない。 今回のソースにクライアントアイランドがなく、実際の生成物にも実行用JavaScriptが存在しなかったことを示している。
測定結果の生データはbuild-report.jsonとして公開する。
PreactとSignalsを入れる境界
「Astroだけで作る」は、対話機能まで素のDOM APIだけで書くという意味ではない。 状態を持つUIが必要になった時点で、その部分だけPreactへ切り出す。
候補になるのは、たとえば次のような機能である。
- 検索語とカテゴリを同時に扱う記事検索
- OS、CPU、GPUなど複数条件を切り替える比較表
- 入力値から料金や性能を計算する記事内ツール
- 複数系列を表示し分けるインタラクティブなグラフ
AstroのPreactインテグレーションは、Preactコンポーネントのレンダリングとクライアント側のハイドレーションを追加するためのものとして提供されている。 その機能が必要になるまで依存関係を追加しなければ、静的な記事へ同じランタイムを波及させずに済む。
Signalsも同じ扱いにする。 検索条件や比較条件のように複数のUIが同じ状態を参照するときには使う価値があるが、記事本文を表示するだけのページには状態管理そのものが存在しない。
採用基準
現時点では、Astroコンポーネントと静的HTMLを既定にする方が、このサイトの用途に合っている。 PreactとSignalsを禁止する理由はなく、必要になる条件を先に決めておく方が依存関係を増やす判断を検証しやすい。
将来、検索や比較ツールを実装するときには、そのIslandが追加するJavaScript量と操作性をproduction buildで再び測る。 そこで初めて、静的HTMLだけだった基準値との差が見える。