ブログをGridsomeからAstroに移行しました。

前回までのあらすじ

体調が悪すぎてずっと寝込んでいます。本当に悲しい。

Astro v2 でブログを作り直しました

ずっと寝込んでいるのですがそれはそれとして Gridsome で構築していたブログを Astro で作り直しました。Gridsome は素晴らしいフレームワークなのですが、2020 年の 11 月を最後にリリースが止まっており、これ以上使い続けるのはリスクが大きいと判断して別のフレームワークに移行することにしました。SSG ならビルドした結果は脆弱性関係ないしそのまま使えばいいだろとも思ったのですが、自分の手元以外でビルドするときに動かないプラグインが出てきそうなのと、2 年以上も開発が放置されているフレームワークを使い続ける自信がありませんでした。

Gridsome のことは本当に好きでして、フロントエンド初心者でもとっつきやすく、カスタマイズ性に優れていたので開発が継続していたら使い続けていたと思います。Vue3 に対応してくれ~~~。

移行前の構成

  • Gridsome 0.7.23
  • JavaScript
  • 素の CSS(WordPress のOmegaというテンプレートを改造したもの)

前のブログもかなり気に入っていたのでプレビューのリンクを残しています。

全文検索は kuromoji で形態素解析した結果をキーワードにすることで実現していました。

移行後の構成

  • Astro v2.3.0
  • TypeScript
  • Tailwind CSS

全文検索は Algolia のフリープランに移行しました。

移行後の PageSpeed Insights

Gridsome で測ったときと同じページで PageSpeed Insights のスコアを計測しました。

モバイルの結果
モバイルの結果
PCの結果
PCの結果

ガンガンガン速。

Gatsby にしなかった理由

Gridsome が Gatsby インスパイアだったため、最初はもとのブログをそのまま Gatsby v5 に移植するつもりで実装を進めました。もともとそこまで複雑なことをしていなかったこともあり、元気がなくても数日程度でほぼ移行できたのですが、ビルドしてみると色々問題があることがわかりました。

ビルド時間が Gridsome の 2 倍以上かかる

Gridsome で 1 分強だったビルドが 2 分かかっても終わりませんでした。記事に比べて画像がほとんどないのに画像の最適化がボトルネックになっているようです。Gridsome は画像の最適化に加えて全文検索用の形態素解析もしていたのですが、Gatsby は形態素解析なしでこの時間だったので、機能を追加したらもっと遅くなりそうな予感がします。

自分の環境が悪いのかと思い Vercel でもビルドしたのですが、手元でビルドするのとほぼ変わらない結果だったため、残念ながら環境の問題ではなさそうです。

gatsby developもなんだか遅い?

gatsby developで適当な記事を表示してもレンダリングまでに毎回体感 2 秒以上はかかる感じで、思ったように開発を進めることができませんでした。これはかなり痛かったです。

画像を含んだ記事の表示がおかしい

これが最も致命的だったのですが、縦長の画像の出力が期待どおりになりませんでした。

Gatsbyのビルド結果
Gatsbyのビルド結果

親要素の max-height に合わせて縮小されるのを期待していました。Gridsome では問題なく最適化されていた部分です。

期待した出力結果
期待した出力結果

子要素のgatsby-resp-image-background-imageが親要素の width と height を無視して元画像の大きさで出力されており、記事に覆いかぶさっています。widthheightが style 要素で指定されているので!importantobject-fit: contain;で上書きしてどうにかしようとしたのですが、思った通りの出力にできませんでした。

画像はほぼ使っていないので最適化は考慮しなくてもいいですし、Gridsome でできていたことができないなら Gatsby にこだわる必要もないな…という結論に至り、フレームワークを選定し直しました。

Astro を採用した理由

ブログ移行時に設定した要件があり、それらを満たすフレームワークを探していました。要件は次の通りで、重要度が高い順に列挙しています。

  • しにそうなミミズレベルで元気がない人間でもドキュメントを読めば簡単に静的な Markdown ブログを作れること。
  • 記事は Markdown で書いているが、将来的に何かしらの CMS へ乗り換える可能性があるため、Markdown と CMS の相互移行が容易であること。
  • MDX が使えること。
  • プラグインが簡単に自作できること。
  • 画像はほとんど使わないので画像の最適化は考慮しない。

Astro は上記すべてを満たしており、なおかつドキュメントがわかりやすく、ビルドするだけでおおよそブログの形式にできたため採用しました。 React と Vue のコンポーネントがどちらも利用できるので今まで作成した資産も活用できます。Algolia が提供しているReact 用の UI コンポーネントがそのまま使用できるのはありがたかったです。

フレームワークコンポーネント 🚀 Astro ドキュメント

Astro を選んでよかったところ

色々ありますが、特に良いと思った箇所を列挙しました。

  • 静的サイト生成に機能が絞られているため、他のフレームワークと比べてシンプルで使い心地がとても良い。やりたいことがすぐできる。
  • React, Vue コンポーネントだけでなく、素の JavaScript も書ける。
  • integration の開発がとにかくわかりやすい。しにそうなミミズレベルで元気がない人間でも直感的に書ける。
  • インストール時に対話型でオプションを設定してくれる Houston がとってもかわいい。
Houston、本当にかわいい
Houston、本当にかわいい

SPA やサーバサイドの処理は求めておらず、ぽちぽち HTML を書く作業感でブログを構築したかったのでまさにうってつけのフレームワークでした。

Astro を使うにあたり苦戦したところ

どちらかというと Astro の使い方よりも Astro のバグで困りました。

VSCode 使用時にastro:contentが見つからずにエラーが出る

他の人も VSCode 使用時に同じエラーが出たようで Issue が上がっていました。エラーが出ていてもビルドはできます。

Cannot find module ‘astro:content’ · Issue #5711 · withastro/astro

最初に npm run devするかnpm run buildすると解消します。

@astrojs/sitemapで出力されるサイトマップに URL が追加されない

Astro にはサイトマップを出力する integration があります。

@astrojs/sitemap 🚀 Astro ドキュメント

@astrojs/sitemapは特にトラブルなく導入できたのですが、生成されたサイトマップを確認したところ 3 桁の数字を含む URL がごっそり抜けていました。 このブログは過去に WordPress で運用しており、その名残でほとんどの記事のパスが/archives/123の形式なので修正が必須です。

原因と解決方法を調べたところ、以下の記事に解答が記載されていました。最初まるで見当違いのところを調査しており困っていたので本当にありがたかったです。

Astro で理想のサイトマップを自作する - Shinobi Works の Web ブログ

ちなみに@astrojs/sitemapで生成したsitemap-index.xmlを Google Search Console に登録すると「サイトマップを取得できませんでした」とエラーになります。多分 XML 宣言が無いせいだと思うのですが、深く調査はしていません。

Astro を使っていて惜しかったところ

苦戦はしなかったけど改善されるといいなぁ、と思った箇所がいくつかありました。

.astro以外でAstro.glob()が使えない

API Reference 🚀 Astro ドキュメント

指定したローカルのファイルを全部読み込んで、パースした結果をオブジェクトで返すAstro.glob()という API があるのですが、.astro以外では使用できないのが残念でした。globgray-matterで無理やり解決した部分があるのでアップデートに期待したいです。

.md/public以外の画像を読めない

記事では![]()構文で画像を表示させているのですが、この場合画像の置き場所が限られるのと、@astrojs/imageが使用できないので画像の最適化ができません。

画像 🚀 Astro ドキュメント

.md ファイル内では標準的な![]()構文や<img>タグを記載することで public/フォルダや、他サーバー上にあるリモート画像を表示できます。

しかし、/public ディレクトリにあるファイルは処理されずにそのまま提供、コピーされます。

画像の最適化や置き場所についてはそこまで困っていないので、元気になったら解決しようと思います。

作業で失敗したところ

ブログのフレームワーク関係なしに心底失敗したと思っているのがテーマ選びです。 自分の元気の都合上、今回はできるだけ作業を簡略化したかったため、必要な機能がすでに実装されているものを選定しました。

テンプレートを販売している企業が配布している無料テーマ(ライセンスは MIT)を使用したのですが、蓋を開けてみると「正しく動いているように見えて実はハリボテ」「実装や表示にバグが多い」といった状態で、バグの修正や機能の実装で逆に工数がかかってしまいました。run dev が通ってトップページと個別記事ページはまともに動いていたため、問題に気づかないまま後戻りできないところまで移行を進めてしまったのが良くなかったです。

使わせていただいてこういうのも心苦しいですが、公式のテーマか、GitHub で Star が多くついている実績あるテーマをベースに開発を始めるべきでした。ただ、レイアウトの設計を省けたのと、Sass は自分で書くよりも早いはずなのでその点は良かったと思います(白目)。

今回使用したテーマは GitHub で公開されていたので、どうしても見過ごせなかった箇所は Pull Request を送ったのですが、 対応してくれるかは微妙ですね…。 (2023/04/29 追記)なんとびっくりマージされました。

雑感

実際に使ってみてとても楽しいフレームワークでした。元気がない人でもすぐ使えるのは本当にありがたかったです。Node.js さえ導入できればあとはどうにかなるので、個人サイトを作ってみたい人や環境が古すぎてブログのビルドができなくなった人の選択肢としても良いと思いました。 今のところビルドの所要時間は 1 分程度で、RSS 作成、サイトマップ作成、Algolia への登録、OGP 用の画像作成もろもろ含んでこの結果なので満足です。

このブログのソースコード: retrorocket/astro-blog: astro で構築したブログ