Astroに入門してみる
こんにちは
noteのフロントエンドエンジニアのiemongです。
最近はメンバーシップの開発等をやっています。
同僚の天才から、なんか技術記事書いて🙏とお願いされたので、最近気になってるAstroってフレームワークについて書こうと思います。
実際に触ってみて、簡単にページを作るところまでやってみました。
Astroとは
とあるように、オールインワンなWebフレームワークです。公式によると、Javascriptで開発できる MPAフレームワークという位置付けらしいですが、静的サイトジェネレータ的な使い方もできますし、アダプターを介せばSSRもできます。ここら辺はRemixと似てますね。
※ Remix: Reactベースのフルスタックフレームワークです。
高速な理由は画面描画時に読み込むJavaScriptを最小限にするためです。JavaScriptを使ったインタラクションが必要な時は、Componentにディレクティブを明示的に指定します。
2022年8月9日にversion 1.0がリリースされました。
Astroの個人的気になりポイントは以下です。
Astro上でReact, VueなどのUIフレームワークを動かせる
Astro Island
それぞれざっくり説明します。
Astro上でReact, VueなどのUIフレームワークを動かせる
これは表記の通りなんですが、astro componentからimportする形で、React, Vue, Svelteで作られたcomponentを直接読み込むことができます。
ただし、UIフレームワーク毎にintegrationを追加する必要があります。
例えば、React Componentを読み込むためには↓の1行をターミナルで実行する必要があります。
yarn astro add react
これによって、react, react-dom, @astrojs/react のnpm packageがinstallされ、設定ファイルのastro.config.mjsにreactのintegrationsが自動で追加されます。
コマンド1つで設定が完了する DXええやんって思いました。
あとは、以下のようにReact ComponentをimportしてAstro上で呼び出せば、表示されます。
---
import MyReactComponent from '../components/MyReactComponent.jsx';
---
<html>
<body>
<h1>Use React components directly in Astro!</h1>
<MyReactComponent />
</body>
</html>
FYI
AstroはFrontmatterみたいな感じで、--- でJavaScriptとTemplateの境界線を設けています。
---
// Component Script (JavaScript)
---
<!-- Component Template (HTML + JS Expressions) -->
このようにAstroでは、様々なUIフレームワークを読み込めるので、既存のコードをそのまま流用できるのに可能性を感じました。
例えば、Vue.js -> Reactにリプレイスするとします。その場合、全てのComponentをVue.js -> Reactに書き換える必要があるため、ページ単位でリプレイスするのがよくあるアプローチだと思います。
ですが、もしAstroで作られたサイトであれば、Component単位でリプレイスが可能になるので、ページよりも細かい単位で移行できるのでは?
と思いました。
Astro Island
Island Architectureという設計アイデアをAstroに落とし込んだものです。
インタラクティブなコンポーネントを島と見なして、非インタラクティブなコンポーネントは海に沈んでいると思ってください。
開発者が設定した表示タイミングで、JavaScriptがhydrateされ、海から島が浮き上がるイメージです。
表示タイミングを設定するのに、 以下の client:loadの部分のようなClient Directiveを使います。
<BuyButton client:load />
その他のClient Directiveは
client:idle : idle状態の時に読み込まれる
client:visible : viewportに入ったら読み込まれる
client:media : 特定のmedia queryを満たしたら読み込まれる
などがあります。
表示タイミングを適切に設定していれば、初回で読み込まれるJSの量をかなり減らせると思うので、TTIの向上が期待できそうです。
やってみた
自分が以前書いた記事をデベロッパーツールで見ながら、途中まで再現したものをcodesandboxにあげてみました。
(全部作るのが中々大変でライフが0になってしまったので、諦めました。)
ざっと、解説すると、↓の図のようにヘッダー, スキ, シェア・ユーザー・公開日がまとまったやつ, 埋め込みを今回component化して、それぞれにClient Directiveを追加しています。(今回はボタンを押すとalertが出るだけにしてます。)
DevToolsのNetworkタブを見ると、client:visibleが設定された埋め込みのcomponentなどはview portに入った後にJSが読み込まれているのが確認できます。
まとめ
今回調べてみた & ちょっと書いてみて思った感想は以下です。
Client DirectiveでJSの読み込みタイミングの制御ができるの良い。
確かに、記事ページのような読み物が中心で縦に長くインタラクションが少ない画面などでは、view portの外側のcomponentは全て client:visibleにして良い気がしました。
もう少し種類が増えると嬉しい。
React, SvelteなどをそのままAstro コンポーネントでimportできるので、コードの資産を流用できるなとは思いつつ、Client Directiveを使うにはある程度Astroコンポーネント上でレイアウトする必要がありそう
Atomic Designで言うtemplate層にあたるComponentをそのままimportしたとしても、大体のケースでは client:load を付けると思われるので、Astro Islandの恩恵を受けたいならtemplate層はAstroで書く。organisms層のComponentを流用するみたいなアプローチが必要そう。
VS Codeにしかextensionがない。
自分はJetBrains製品を使ってるので、あれば嬉しいなと。ちょっと調べた感じ、頑張ってる途中らしいです。
明日から本番環境で使うぞ〜〜〜みたいな選択をするには、まだ覚悟が必要そうですが、個人開発や自身のブログなどで採用してみる分には色々楽しめそうです。
noteではAstroの採用実績はまだですが、フロントエンドエンジニア絶賛募集中なので、興味がある方はぜひご応募ください!
終わり