信頼度ランク
| S | 公式ソース確認済み |
| A | 成功実績多数・失敗例少数 |
| B | 賛否両論 |
| C | 動作未確認・セキュリティリスク高 |
| Z | 個人所感 |
Astroで没入型サイトを作る設計判断:住友金属鉱山「絶滅危惧野菜」を読み解く
endangeredveggies.smm.co.jpはAstro + Three.js + GSAPで構築された没入型サイトです。なぜSPAではなくAstroのMPAアーキテクチャが選ばれたのか、コンポーネント設計の意図を実際のDOM構造から分析します。
一言結論
Three.jsとGSAPで重い没入型演出を入れるサイトにAstroを選んだのは「ページ遷移がない1ページ完結」と「JSを必要な箇所にだけ差し込むIslands設計」が噛み合うからで、Next.jsやNuxtでやるとhydration負荷が邪魔になる。
住友金属鉱山の「絶滅危惧野菜プロジェクト」は、黒背景に野菜が3Dで浮かび上がる没入型のWebサイトです。一見すると「これはReactかVueのSPAだろう」と思いますが、DOMを覗くとAstroで作られています。
<!-- 実際のDOM(一部) -->
<html lang="ja" data-astro-cid-sckkx6r4>
...
<link rel="stylesheet" href="/_astro/index.Cmf642l6.css">
<script type="module" src="/_astro/Layout.astro_astro_type_script_index_0_lang.B6F7olBf.js">
data-astro-cid-* 属性が20種類以上付与されており、Astroコンポーネント単位で細かく分割されていることがわかります。この記事では、なぜこの種のサイトにAstroが合うのかを分析します。
Astroが選ばれた理由を推測する
理由1: 1ページ完結のサイト構成
このサイトはSPA的なルーティングを持ちません。ハッシュリンク(#about, #map, #vegetables)でセクションに飛ぶだけの1ページ完結型です。Next.jsやNuxtの「ルーティング」や「レイアウトの共有」は不要——つまりフレームワークの最大の売りが使われない構成です。
Astroはこの場合、余分なランタイムJSをゼロにしたままコンポーネント分割と静的ビルドだけを提供できます。
理由2: Islands Architecture が Three.js と相性が良い
Astroの Islands Architecture は「HTMLの中でJSが必要な部分だけをクライアントサイドで動かす」設計です。
このサイトの構造はおそらく次のようになっています。
<Layout> ← Astroコンポーネント(サーバーレンダリング)
<Header /> ← 静的HTML
<HeroSection /> ← 静的HTML + 装飾
<VegetableCanvas /> ← ★ここだけクライアントJS (Three.js)
<MapSection /> ← ★ここだけクライアントJS (インタラクティブ地図)
<PartnersSection /> ← 静的HTML + モーダル
<Footer /> ← 静的HTML
</Layout>
Three.jsのキャンバスはページ全体ではなく特定セクションにだけ存在します。Astroなら client:visible ディレクティブでビューポートに入った瞬間にだけThree.jsを初期化できるため、初期読み込みでは重いJSを一切実行しない設計が可能です。
React/Vue SPAだと、フレームワークのhydration → Three.js初期化 が直列で走るため、黒画面の表示までが遅くなります。
理由3: CSS Scopingの恩恵
/* /_astro/index.Cmf642l6.css(ビルド生成) */
[data-astro-cid-sckkx6r4] { ... }
[data-astro-cid-24dqbciy] { ... }
Astroはコンポーネントごとに data-astro-cid-* を振ってCSSをスコープします。BEMやCSS Modulesを自前で管理する必要がなく、ビルド時に自動でハッシュ化されます。
このサイトでは20以上のスコープIDが確認でき、レイアウト・セクション・モーダル・地図UIなど細粒度でコンポーネント分割されています。
CSSの4ファイル分割
ビルド出力が4つのCSSファイルに分かれている点も注目です。
<link rel="stylesheet" href="/_astro/index.Cmf642l6.css">
<link rel="stylesheet" href="/_astro/index.JAn8hKy2.css">
<link rel="stylesheet" href="/_astro/index.Cw1C-G7L.css">
<link rel="stylesheet" href="/_astro/index.HgQTDe5K.css">
Astroはコンポーネント単位でCSSを抽出し、使用箇所ごとに分割します。ブラウザは必要なCSSだけをレンダリングブロックとして処理するため、巨大な単一CSSよりもFirst Contentful Paintが速くなる設計です。
JSバンドルが1つだけ
<script type="module" src="/_astro/Layout.astro_astro_type_script_index_0_lang.B6F7olBf.js">
ページ全体で読み込まれるAstro固有のJSバンドルはたった1つです。このバンドルにThree.js・GSAP・ScrollTrigger・IntersectionObserver制御がすべて入っています。SPA フレームワークなら追加でルーター・状態管理・hydrationのランタイムが乗りますが、Astroではそれがゼロです。
Content Security Policy の厳密さ
<meta http-equiv="Content-Security-Policy" content="default-src 'self' data: 'unsafe-inline' 'unsafe-eval' blob: ...">
CSPヘッダーがmetaタグで設定されており、Google系(GTM/GA4/Ads)とFacebook、DataSign(Cookie同意)のドメインが個別にホワイトリストされています。unsafe-inline と unsafe-eval が残っているのはThree.jsのシェーダーコンパイルとGTMの動的スクリプト注入のためと推測できます。
企業サイトとしてCSPを入れていること自体がこだわりです。多くの企業キャンペーンサイトはCSPを設定すらしていません。
こだわりポイント
- WebP画像の統一:
/assets/images/配下がすべてWebP。旧ブラウザ向けのfallbackは見当たらず、モダンブラウザに絞り切っている - プリロード戦略:
<link rel="preload" href="/assets/images/loading.gif" as="image">でローディングGIFを最優先で読み込み、黒画面→ローディング→本コンテンツの遷移を滑らかにしている - コンポーネント粒度: 20以上のAstroコンポーネントIDが確認でき、セクション単位ではなくUIパーツ単位で分割している。保守性を考えた設計
- Photography クレジット: 右下に「Photography by Janny Suzuki / Terumi Takahashi」が常時表示。野菜の撮影をプロカメラマンに依頼し、それ自体をコンテンツの柱に据えている
Astroが合わないケース
逆にこの構成が合わないケースも明確です。
- 複数ページ間でユーザーの状態(カート・認証)を共有する必要がある場合
- ページ遷移アニメーションがある場合(Astro View Transitionsで一部対応可能だが、Three.jsのシーン遷移は自前が必要)
- リアルタイムデータ更新が多い場合
このサイトは**「1ページで完結・状態管理不要・重いJSは局所的」**という条件がすべて揃っているため、Astro Islands が最適解になっています。
参考: