少し前にこのブログをNext.jsからAstroにリプレイスしたのですが、リプレイス前には60ポイント程度だったPageSpeed Insightsのスコアがリプレイス後にはほぼ100ポイントになり、大幅なパフォーマンス改善をすることができました。
本記事ではAstroというフレームワークの紹介と、実際にAstroのを使ってみた感想をお伝えできればと思います。
Astroとは?
Astroの公式ドキュメントでは次のように述べられています。
Astroは、ブログやマーケティング、eコマースなど、コンテンツ駆動のウェブサイトを作成するためのウェブフレームワークです。Astroは、新しいフロントエンドアーキテクチャを開拓し、他のフレームワークと比較してJavaScriptのオーバーヘッドと複雑さを低減することで知られています。高速でSEOに優れたウェブサイトが必要なら、Astroが最適です。
ここで大事なのは当然太字になっている部分、すなわち「コンテンツ駆動のウェブサイト」です。
コンテンツ駆動のウェブサイトというのは上記引用の通り、ブログやホームページなどコンテンツが載っているだけの「ウェブサイト」のことを指します。
逆を言うと、XやFacebookのように頻繁なデータフェッチが必要だったり、人によって表示されるコンテンツが動的に変わるような、いわゆる「Webアプリケーション」には向かないということです。
ここからもわかる通り、Astroにははっきりと向き不向きが存在しており、Next.js等通常のフレームワークのように「とりあえずこれを使えば何でも作れる」といったフレームワークではありません。
ただし、使い所さえ間違えなければ抜群の効果を発揮するという類のフレームワークです。
実際に使ってみた感想
メリット
開発体験が改善した
Next.jsで開発していた際にはバンドラーがwebpackだったこともあってローカルでのサーバーの立ち上げやページ遷移がかなり遅かったです。
この問題はかなり深刻で、以前にもMSWを使ってAPIアクセスをモックしたり、APIアクセスの最適化をしたりと様々な施策を行っていました。
今回Astroへリプレイスしたことによってバンドラーがwebpackからviteになり、結果的に以前行った施策を上回る改善効果を得られました。
また、Next.jsで開発していた時には正直使っていない機能がかなり多く、開発に際しての学習コストがただただかかっているような状況でした。
Astroは機能がかなり絞られているので学習ハードルが低く済んだのも開発体験的にはかなり良かったです。
ページパフォーマンスが劇的に改善した
タイトルでも述べている通りページパフォーマンスはかなり改善しました。
Next.jsでの実装も開発当初はページ数が少なかったからか80ポイント程度のスコアが出ていたのですが、しばらく見ないうちに60ポイント前後になってしまっていました。
これがAstroにリプレイスしてからは、安定的に100ポイント近くのスコアが出ています。
この結果に最も大きく寄与したのはやはりAstroのアイランドアーキテクチャによるパフォーマンス最適化でしょう。
AstroはNext.jsなどと違いSPAではありません。
その代わりMPAとしては完全に最適化されており、build後の各ページの生成ファイルはhtmlのペライチです。
client:loadディレクティブをつけていなければscriptタグすら含まれません。
Next.jsではJavaScriptのロードが重すぎることがパフォーマンスに最も大きく影響していたのですが、Astroでは見事にその部分の課題が解決された形です。
様々なUIフレームワークに対応しているためリプレイスが容易だった
AstroはReact、Vue、Svelteなどの多くのUIフレームワークのコンポーネントをサポートしています。
極端に言えば以下のように最上位のコンポーネントのみをAstroコンポーネントにして、それ以下をすべてReactコンポーネントにすれば既存コンポーネントのほとんどを使いまわしながらすぐにページを表示することができます。
---
import MyReactComponent from '../components/MyReactComponent.jsx';
---
<html>
<body>
<MyReactComponent client:load />
</body>
</html>
ただし、上記のようにclient:loadをつけるとその配下のコンポーネントではJavaScriptが読み込まれてしまうので、このままだとAstroのアイランドアーキテクチャを存分に活かすことはできません。
Astroのアイランドアーキテクチャを活かすのであれば最低でも動きのないコンポーネントとその親コンポーネントはAstroコンポーネントとして作成するべきです。
とはいえ、ReactコンポーネントをAstroコンポーネントに置き換える際にも親コンポーネントから計画的に置き換えていけば画面を崩すこと無く実装することが可能です。
そういう意味でも他のフレームワークに比べるとリプレイスはかなりやりやすいと思います。
デメリット
CSS in JSが使えない
これは正直かなり痛かったです。
以前はMUIを使っていたのですが、MUIではCSS in JSが使われているためそのままAstroコンポーネントの配下に置いてもCSSが効かないです。
今回の場合ページネーション等の機能をMUIに依存していたので、この部分のコンポーネントは新規で作成する必要があり工数がかかりました。
この件に関してはGithub上にissueはありますがまだ開発は行われていないようです。
Astroコンポーネントはstorybookでサポートされていない
これも正直痛いです。
コンポーネント駆動で開発をするならstorybookは必須のライブラリといっても過言ではありません。
加えて、Chromaticによるビジュアルリグレッションテスト等を行うのであれば一層storybookの重要性は増します。
個人開発程度であればこれでも十分開発することは可能ですが、チーム開発だと特に不便しそうな部分ではあります。
これについてもGithub上にissueがあるだけの状態です。
日本語資料が多くない
これは最初こそ不便でしたが他のデメリットに比べると痛手ではありませんでした。
確かに資料は少ないのですが、Astroは機能がそこまで複雑ではないので公式資料だけでかなりのところまで理解を深められます。
また、公式資料は結構しっかりと日本語に翻訳されているのでその部分だけ読めば十分な開発が可能でした。
とはいえ、ページネーションと動的ルーティングを同時に使う場合など、細かいユースケースへの対応は公式ドキュメントだけだと詰まる部分もあったので今回はデメリットとしてあげています。
まとめ
今回はAstroについて使ってみた感想を書きました。
本ブログのAstro実装は以下のリポジトリにあります。
また、Next.js実装も以下のリポジトリにあるので興味があれば覗いてみてください。