ブログをHexoからGatsbyに移行した

Gatsbyで作ったブログのスクリーンショット

Caution

この記事はHexo(2023年4月17日以前)、またはGatsby(2024年4月13日以前)時代の記事だよ❗ 現在のブログとは見た目や機能が異なる可能性があるよ❗

ついにHexoからGatsbyにSSGを切り替えた。 なんとGatsby Themeも自作❗ マジで大変だったけど、それに見合うメリットがあったと思う。

技術的な詳細は Qiita に投げるとして、ここでは概要を説明する。

HexoのときとGatsbyのときとで見た目比較

どこが変わったのか新旧比較しようのコーナー😎

トップページ。 (この画像比較スライダーも語りたい。後述。)

Hexoで作ったブログのスクリーンショット メインページ Hexoで作ったブログのスクリーンショット メインページ

Gatsbyのほうが全体的に文字がでかい。 ダークテーマに変更したのでイケてるよね。 あと、私のアイコンが右に出てるのも承認欲求モンスター的にはgood。

タグページ(カードレイアウト)はこんな感じ。

Hexoで作ったブログのスクリーンショット カードレイアウト Hexoで作ったブログのスクリーンショット カードレイアウト

これも良くなったよね❗ Hexoのときは縦長画像と横長画像を並べたときに段組みがガタガタだったけど、 Gatsbyでスマートに収まってる。 カード数も2列に絞ったので、写真が見やすい。

Gatsbyの良い点その1: 画像の表示が早い

Gatsby最大のメリットだよね。 画像の表示が早い。

HexoのときはPC向けにもスマホ向けにも同じ1枚の画像を配信してた。 ただ、当然、PCとスマホだと解像度が違うわけで、 PC向けの高解像度な画像はスマホにはオーバースペック…。 スマホで見てる人にとっては、無駄に重い画像になっちゃって、ページの表示が遅くなってた。

これを解決するには、スマホ向けとPC向けの2種類の画像を用意する必要がある。 だけど、これがまぁめんどくさいわけw 手動でやるのは地獄。

Gatsbyはこれを自動でやってくれるんだな〜。 私はLightroomでJPEGを吐いて、あとはGatsbyにおまかせ。楽ちん○ん。 (ついでにHexoでやってたWebP変換スクリプトの実行も不要になった。)

例えば、今の設定だと↓の解像度の画像を自動生成するのね。

  • 480px
  • 1024px
  • 1920px
  • オリジナル(1920pxを超える場合のみ)

私のiPhone 12 ProのViewportの横幅が390pxでしょ。 だから最小の480pxの画像をDLすれば済むわけ (あ、実際には、Retinaディスプレイだから倍の780pxかも…)。

Hexoのときは1600pxの画像しかなかったので、だいぶ効率化してると思う。

Gatsbyの良い点その2: ReactとTailwind CSSで書ける

嬉しい。 HexoのときはEJSで書く必要があったんだけど、あれがやっぱ慣れなかった。 あと、生のCSSも闇なのでなるべくいじりたくない。

ダイヤグラム生成くん はReactで書いてたので、技術的にも慣れてるのは大きなメリット。

Reactといっても、かなりライトに使える。 一般的なReactアプリでいじる useEffect() とかは一切使わない(使ってもいいけど)。

それよりかは、再利用可能なWebコンポーネントとして利用する側面が強い。 Tailwind CSSでスタイルも一緒に記述しちゃって、箱をどんどん作っていくイメージ。 Webページ全体は箱の組み合わせで作る。

Gatsbyの悪い点その1: サイトのファイルサイズがでかい

画像の表示が早い のと表裏一体なんだけど、サイトのファイルサイズがでかい。 スマホ向けやPC向けに複数解像度の画像を生成するので、その分重くなる。 今の設定で計測したら↓。

  • Hexo: 約800MB
  • Gatsby: 約2GB

2倍以上違う。 ただ、これはもうちょっと改善できるかも。 現状はLightroomが長編2048pxで画像を生成してて、Gatsbyの解像度の刻みが480px, 1024px, 1920px。 1920pxと2048pxが近すぎて、意味がなくなってるんだよね。 これを2048pxに一本化できれば、1.8GBくらいにはなるんじゃないかなあ。

さらに、記事本文中の画像でJPEGも生成してるんだけど、これも止めればもっと軽くなるはず。 pluginの設定上、必ずJPEGを生成しちゃうんだけど、オフにできないか 作者に相談中

Gatsbyの悪い点その2: ビルドが遅い

  • 刻み: 480px, 1024px, 1920px
  • 形式: JPEG, WebP

の設定でクリーンビルドしたら30mくらい。

これも画像生成が多いせいだと思う。 テキストだけだったら、Hexoより早いか、どっこいどっこいぐらいじゃないかな。

解像度の刻みをデフォルトの5段階にして、 さらにAVIFの生成もしようとしたことあったけど、3h待ってもビルドが終わらなかったw

画像が多いブログを作る場合は、可能な限りWEBPだけに絞って、 刻みも必要最低限に絞ったほうが良いね。

Gatsbyの悪い点その3: ちょっと複雑なことしようとするとすぐ闇

多分、Gatsbyを始めた人は gatsby-starter-blog とかを参考に始めると思うんだけど、 これ本当に参考レベルのものなんだよね。

致命的なのはページネーションがないんだよね。 記事が80個あったら、80個が全部1ページに並ぶの。実用に耐えない…。

あと、結局GraphQLの型定義からは逃げられないのも闇。 例えば、記事のURLを決める slug のフィールドをFrontmatterで指定したりするとき、 型定義がないと、 slug のある記事が1つもなかったらエラーになっちゃう。 これは、存在するフィールドについては型を自動で推測してくれるからで、ないもんは推測してくれない。無理。

エラー回避のためにすべてのフィールドを持った記事を作っておくってのもナンセンス…。 なので、型定義するかって話になるんだけど、これがやたら闇なんだよなあ…。

このへんcreateFieldExtension() あたりが闇。 Nodeのフィールドは2種類あって、単純にデータを取得できるものと、 resolver を介さないと取得できないものがある。 後者のフィールドを利用したフィールドを作る場合、これもやはり resolver が必要になる。 resolver の定義には createFieldExtension() が必要で、 これは引数が4つも5つもある…。

書いててクラクラしてきた。ともかく、シンプルじゃないよ。

gatsby-transformer-remark が作ってくれるフィールドは resolver を介するものだらけなので、 これを使ってブログを書く人は↑のクラクラする話を理解しないといけないのね。はぁ。

まぁ、なんとか理解したのでこのブログがあるんだけど、学習コストは高いよね〜。

あとがき

Gatsbyは手放しに勧めれたもんではない。 世の中でよく使われているだけはあって、柔軟で自由度の高いツールだと思う。 が、ブログに使うとなると自由度が高すぎて闇の部分を見つめなくてはならない。

今は Astro とかが流行りなのかな❓ Gatsbyの闇を見つめてるときに浮気しそうになったけど、耐えた。 今度の引っ越しタイミングでもまだ流行ってたら使ってみよう。

もっとも、あと数年もしたらRust製のツールが流行ってるだろうなあ。 もっというと、WebサイトそのものがAIに取って代わられるかも。