静的サイトジェネレーターを比較して再びHugoにした理由(2021年版)

2年前に静的サイトジェネレータ(SSG)を比較しました。やはり動的プログラム(代表例 WordPress)のようにセキュリティリスクとイタチごっこになる仕組みと違って、純粋なHTMLページでしかないSSGは運用面の負担が少なくていいなと身にしみて感じます。

静的サイトジェネレーターの比較とHugoに決めた理由
静的サイトジェネレーターの比較とHugoに決めた理由
https://fand.jp/static-site-generator-trends/
WordPressの運用をやめて静的サイトジェネレータへ移行するために Jekyll, Hugo, Hexo, Gatsby を比べた結果 Hugo を選択した理由をまとめます。

以前結論を出した通り静的サイトジェネレーター Hugo で全く問題なかったのですが、サイトのレイアウトを変更しようと思ったこのタイミングで他の技術にも触れておこうと思い最近の動向(2021年10月時点)をチェックしましたので、改めてアップデートしたいと思います。

なお、静的サイトジェネレーター全体の動向比較というよりも、特定の条件に絞って調べたニュアンスになります。そして、最初に結論を書いてしまうと結果的に Hugo の利用を継続することに落ち着いています。

静的サイトジェネレーター(SSG)とは何か

本記事はSSGそのものを説くものではなく、ある程度「SSGとは何か」が分かっていて、膨大に選択肢のあるツールのなかから選定の後押しとなるひとつの目線を情報提供することが目的です。ですので簡単におさらいをするに留めます。

静的サイトジェネレーターは、コンテンツ管理システム(CMS)の代替手段です。CMSといえばここ数年来の代名詞は WordPress (PHP) がダントツでしょう。これは、Webコンテンツの管理、Webページの生成、およびテンプレートの実装が主な役割です。WordPress について強いて欠点を挙げるならば以下の観点があります。

  • 利用者が多いため、WordPress に対する不正アクセスを試みる不正プログラムが多い
    • ただし、セキュリティ更新も含めてお任せのサービスを選択すればこの驚異も回避可能
  • 動的プログラムなので多少遅くなる(あくまで静的サイトに比べて相対的にはの意味)

いずれもデメリットといえるほど致命的なものではなく、多くの場合・多くの利用者においてはメリットの方が圧倒的に上回ります。驚異の裏返しにはなりますが、利用者が多いということはそれだけ知恵や解決策・ツール(Pluginやテーマ)も充実しており、それらを活用することで一気にプロ並みの複雑なサイト運営ができてしまうのは非常に魅力的でしょう。

一昔前はセットアップのためにサーバー・データベースの知識を多少なり必要としていましたが、最近は WordPressを数分でセットアップできるサービス も多数登場しています。そうなると、SSGを何のために利用するのかを見定めなければ、SSG化の恩恵を受けられず工数だけを無駄にすることになりかねません。

比較観点は多数あるでしょうが、例えば以下のような目線でしょうか。

  • コンテンツ(記事)を更新するのは誰なのか。
    • 大人数になればなるほど、CMSのような管理画面に向かって作業をしたほうが記事更新の競合が起きなくてよいといえる
    • 利用者のITリテラシが低いほど、直感的なエディタを用いて記事を執筆できたほうが心理的な負担を抑えることができる(ITリテラシが低い人に対して、いきなりMarkdownフォーマットで書くことを要求しづらいでしょう)
  • サイトの更新頻度や、想定されるアクセス数はどうなのか。
    • ライターが更新を頻繁にするためのUX(=動的プログラムの活用)と、SSGの特徴である爆速のレスポンス(その犠牲としてサイトコンテンツの更新に関するUXを犠牲にしがち)はトレードオフの関係にあります。
    • サイトの閲覧者が非常に大きくて少しでもパフォーマンスを良くしたい場合は、間違いなくSSGを利用すべきでしょう。
  • 全く異なる観点として、エンジニアとしての技術的関心(モチベーション)も無視できないでしょう。

もちろん、Headless CMS を利用したり、動的プログラムであってもキャッシュ設計を上手にしてレスポンスを爆速にするなど解決策は無数にあるのでひとことで相関を表現しきれるものではありません。ただ、ゴリゴリにカスタマイズしてしまうと今度は開発工数という別の要因も出てきますので、ここでは「それらツールを標準+αで使ったら」という目線で捉えていただくのがよいかと思います。

さて冒頭から長くなりましたが余談はこのくらいにして、本題に移ります。本記事で触れるSSGは非常に限定的です。以下のサイトに多数のSSGがリスト化されていますので、もっと幅広く探したい場合はここがヒントになるかと思います。(2021/11/14時点 333個)

Static Site Generators - Top Open Source SSGs | Jamstack

SSGの技術選定

今回、新たにSSGを選定するにあたっては Javascript 系のフレームワークに着目しました。やはり SPA (Single Page Application) しかり、Web技術トレンドとして Node, npm, yarn を中心とする技術スタックは嫌でも触れなければならない時代です。そのため、できるだけ Node で解決する技術スタックに移すことを考えました。

以下、全て主観(現在の自身におけるモチベーションとして)です。

最近の技術的関心

  • Javascript 系をベースにした仕組みであること(JSMStack)
  • Headless CMS でコンテンツ管理できること
    • 本記事では主役ではないので詳細割愛しますが、 Contentful を採用しました。
    • なお補足ですが、 Headless CMS の話と SSG フレームワークの選定はそれぞれ別のもですので、「Contentfulを使わないからこの記事の内容は関係ないな」というものではありません。SSGフレームワーク選定の目線で少なからず参考になると思います。
  • デプロイ先として Netfly などの配信プラットフォームを使えること
    • “生成したHTMLをどこのサーバーに配置するか” という問題ですので、配信プラットフォームは何でも構いません。

あわせてSSGに求めること

  • Markdownでのコンテンツ執筆は継続したい
    • どこかでSSGに飽きたときの移植性を考慮したもの
  • 画像をもっと便利に扱いたい
    • Markdown中心にコンテンツ管理をしようとすると、画像ファイルのは位置や、画像リンクの挿入、画像タグの漏れなき挿入(widthやheight、title …)など手運用するには面倒くさすぎるのが本音
  • テーマをそこそこ選びたい。一方で、テンプレート構文がシンプルで学習コストが小さいようならば、サイトデザインはあとから作り変える選択肢もとれるので妥協可能
    • ゼロからデザインを起こすのは面倒くさい。ちょっとの学習コストでそれっぽくしたいので、何らかのベースとなるデザインを活用したい
  • Hugoみたいに手軽なSSGであってほしい
  • 無難な答えでさっさと決めてしまいたい

Hugo で記事を書いていて思うのが、 hugo server でプレビュー用のローカルサーバーを立ち上げて執筆し、その内容は瞬時に反映されて待ち時間のストレスなく表示確認ができ、大部分ではとても満足しているのですが、とにかく画像の管理や利用が面倒でした。個人的には割と致命的なので何とかできないかと考えたのが一番大きいモチベーションです。

Jamstack エコシステムも繁栄しているため、困っていることについては何かしらの解決策がすぐに見つかるだろうと期待しました。といっても、シンプルなWebページを作るだけならばSSGフレームワークが有する標準機能で事足りてしまうと思うので、とっつきやすさや相性による部分が第一かなという印象です。

SSGの選定候補

ツールの数が膨大すぎて、とてもすべてを調べきれません。ざっくりと絞り込むために以下の記事を参考にしました。

Pick the Best Static Site Generator for 2021 - Snipcart

  • NEXT.js (Javascript)
  • 11ty (Javascript)
  • Gatsby (Javascript)
  • Nuxt.js (Javascript)
  • HUGO (Go)
  • jekyll (Ruby)

Jekyllは、SSGの時代を開拓した(?)昔からあるツールです。個人的に好きなRuby言語製なのですが、今回の選定コンセプトから外れるので除外します。また、NEXT.js (React) と NUXT.js (Vuejs) がポジショニングとしては似ていると思うのですが、SPAの選定トレンド的には React に分がある印象ですので、Vuejs製の NUXT.js はここでは除外します。

#なお Vuejs は、SPAとして私が初めて触れたフレームワークで思想は割と好みでした。開発チームの特徴にあわせて適材適所で採用するのはアリだと思っています。

一方で、別の統計によると、 Gatsby と Next.js が際立っているのがわかります。

出典 State of Frontend 2020 Report – frontend development trends | TSH.io

さて、ここまでで残るのは3ツール。最初に関心をもったのが、11ty(イレブンティー)と呼ばれるSSGです。

11ty(イレブンティー)

For example, Eleventy makes it easy to consume external content via an API at build time, something some other traditional SSGs do not yet do or do with significant limitations.

  • フレームワークベースのSSG(高度化して複雑になっていっているSSGフレームワーク)に対するアンチテーゼとして作られている
  • MozillaがFirefox拡張機能のドキュメントやMDNのサイトなどに採用しているらしい
    • Mozillaの移行記事 To Eleventy and Beyond - Mozilla Hacks - the Web developer blog
    • もともとJekyllで運用していたが、もろもろのカスタマイズが積もって激遅になったのを問題視して移行プロジェクトを立ち上げ。選定にあたっては、Jekyllで使っていた Liquid テンプレートがそのまま利用できるのがメリットだったようです。言い換えると、その他のフレームワークは全面的なコードの書き直しが発生してしまうのでネガティブだった様子。

上記サイトによると

eleventyが選ばれた主な理由の1つは、Jekyllとの類似性が十分にあり、大幅な書き換えなしでサイトを移行できることです。対照的に、HugoとGatsbyはどちらも大幅なリファクタリングが必要でした。また、サイトを移植することで、事前の変更が少なくなり、すでに本番環境にあるサイトとの同等性を維持することに集中できました。

Jykillでは10分のビルドを要したものが 11th では3秒で終わったという体験も記載されていました。 .liquid テンプレートをそのまま利用している例も見れます。

mozilla/extension-workshop: https://github.com/mozilla/extension-workshop/tree/d0bcb9d094ba0e0b068d6e48cbf935f9fd0ed4ac/src/layouts

11thy が対応している Template Languages: https://www.11ty.dev/docs/languages/

  • HTML .html
  • Markdown .md
  • JavaScript .11ty.js
  • Liquid .liquid
  • Nunjucks .njk
  • Handlebars .hbs
  • Mustache .mustache
  • EJS .ejs
  • Haml .haml
  • Pug .pug
  • Custom .*

システムをゼロから立ち上げるならば好きなものを選べばいいわけですが、過去の技術資産を引き継がなければならない事情においては、これだけの選択肢は有り難いですね。

Next.js

Next.jsとは何かを把握するために、公式サイトの見出し文を確認します。

The React Frameworkfor Production. Next.js gives you the best developer experience with all the features you need for production: hybrid static & server rendering, TypeScript support, smart bundling, route pre-fetching, and more. No config needed.

  • Reactフレームワークをプロダクションレベルで手軽に提供するためのフレームワーク(意訳)
  • SSGのほかSSRもできる
  • TypeScriptもサポート
  • ゼロコンフィグ(実用的にするためにどの程度まで必要なのかは分からないが)

対して感じること。

  • SSRもできるがゆえに、オーバースペックな感も否めない
    • 今回、Web上の管理画面のような動的アプリを作りたいわけではない
  • Getting Started を見ただけでも既にJSX(Reactで定番のHTML生成のための記述)がガッツリ登場している。
  • WordPressのコンテンツをコンテンツソースとして使えるのも標準で完備。まさに、Headless 的な利用の一例です。

急成長中のフレームワークの認識。もともとはSSRとして誕生した側面が強かったらしいのですが、現在はSSGが推奨されています。SSR何それ?という方は以下の通り概要を理解しておけば不都合ないと思います。

  • 事前にHTMLを吐き出してコンテンツ(ページ)を確定させておくものがSSG
  • ユーザー(クライアント)がサーバーにアクセスしたタイミングでコンテンツ(ページ)の内容が確定するのがSSR (Server Side rendering)

We recommend using Static Generation over Server-side Rendering for performance reasons. Statically generated pages can be cached by CDN with no extra configuration to boost performance. However, in some cases, Server-side Rendering might be the only option.

公式より引用 Basic Features: Pages | Next.js

Next.jsに対する解釈

Next.jsを調べていると、Reactひとつでクライアントサイドもサーバーサイドも完結できるが強みのひとつと読み取れます。一方で、何でもReactで解決しようとするからそういう問題が起きるんじゃないのかと感じました。

SPAだと大部分のクローラーが読めないからSEOで不利とか、OGPが読めないといった問題は現時点においては当たり前ですし、それに対してSSRで解決せざるをえない状況もまさにその通り。そしてそれぞれ異なる設計・実装をしなければならない課題に対して、Reactという技術スタックひとつで両方を解決できるのは、非常に嬉しいシーンがあるのもまた事実だと思います。

ただ個人的には、とあるHTMLのレンプレート(テンプレートエンジン)に対してコンテンツ(データ)を流し込むことでHTMLを中心としたWebサイトが完成するオーソドックスな使い方でのSSGが好みなので、SSGツールという文脈における React + Next.js の議論は、あまりしっくりきませんでした。“React アプリだけど、静的HTMLを吐き出しておいてレスポンスを更に改善したいときはあるよね。そういう時のためにSSGとしての使い方をする手段もあるよ” という従属関係での文脈の方がしっくりきます。

となると、そもそも React という、それなりの専門性を必要とする技術を大前提としたSSGツールは目的に沿っていません。結果的には Next.js は見送りました。もはや屁理屈というか好みの話なのですが、“SSRもできるということ=それ相応に複雑であり、シンプルではないということ” という捉え方をしました。「さっさとテンプレートでそれっぽいサイトを作りたい」を優先事項としていたので、Reactでガリガリとコーディングしていく時間とのコストバランスを考えると不都合に感じました。

SSGフレームワークって、HTMLが何となくわかっていればそれなりにカスタマイズできる程よい難易度も大事なのではないかと思います。あくまで私見であり、まさに何を目的にSSGツールを選定するのかが問われる部分だと思います。

Gatsby

2019年にもSSGを比較しました。

Gatsbyから記事を書き出すためのソースコンテンツの扱いに関しても指定方法が多種存在します。Markdownさえもplugin (filesystem)を使うことになるようです。

細かい説明を端折ってしまいますが、Gatsbyはスキャフォールド機能があって Gatsby Starter を用いることで初期導入が非常に簡単である一方、カスタマイズをしようとするならばプログラミングって感じです。語弊があるかもしれませんが、 rails new & rails g scafoold しているような気分でした。

確かに、Blog関連のStarterを用いることで、めっちゃSPAっぽいカッコいいサイトがスピーディーに立ち上がったのですが、そこから手を入れていこうとすると React + GraphQL + Gatsby の思想理解・・・というように、学習コストが気になりました。慣れの問題だと思うのですが、Nodeスタックの初級者(下の上か中の下か、くらいのレベル)が1日でそれっぽいサイトを完成させる目的で選ぶものじゃないと感じたので、改めて不採用に。

何よりも億劫に感じたのが、自由度が高すぎてデータスキーマを考えるところからしなければならない、という点でしょうか(調べればベスプラはあるんだと思いますが)。ブログフレームワーク(データ構造)+テーマ(HTML、CSS)が綺麗に棲み分けできている WordPress のようなシステムの強み・弱みを改めて感じました。WordPressの場合は、データスキーマがほぼ決まっているからこそ、「テーマ」をワンクリックでガラッと変更できるわけですね。

Plugableであること

Javascript界隈のSSGとしてはNext.jsよりも先駆けであることから、SSGとしての機能はまだまだGatsbyの方が充実しているような表現を見かけました。GatsbyとNextの勢力図や追い上げの構造までは調査していません。プラガブルであるということは色々カスタマイズが効いて、技術的関心としてはとてもありますし、知れば知るほどきっと楽しいと思います。

  • gatsby-plugin-sitemap
  • gatsby-plugin-robots
  • gatsby-plugin-remark (Markdown)
  • その他多数

Contentful (Headless with Gatsby)

Headless CMS である Contentful が正式提供している Starter もあります。

Contentful が提供している starter を見ると、HTMLテンプレートを元に静的サイトを生成するのではなく React アプリそのものということがよくわかります。

https://github.com/contentful/starter-gatsby-blogsrc/ 配下の js ファイル参照)

Reactを日頃使っていないと、ちょっとしんどいですね。カスタマイズが億劫だったので放棄しました。

最終的にHugoに戻る(Contentful-hugoを添えて)

上記の通りJavascript ベースのSSGを探しつつ、自身がSSGに求めるものとしては 11ty が近いと感じたので実装の進めていました。ただ、Contentfulからデータを取得してサイトのレイアウトに反映する部分でキャッシュが効いたり効かなかったり?おかしな挙動をしていて、気持ちよくサイトデザインが進められませんでした。(11tyの問題ではなく、Contentfulとの連携部分の問題か、それかNode関連の設定の不備であり、いずれにせよ自身の環境問題のはずです)

あれこれ設定を見直していたところ、ふと Hugo + Contentful の関係性について調べてみたら、非常に完成度の高い npm package を発見してしまいました。

GitHub - ModiiMedia/contentful-hugo: A CLI tool that pulls data from Contentful and turns it into markdown files for Hugo and other static site generators. It also includes an express server that can be used for local development and content previews
GitHub - ModiiMedia/contentful-hugo: A CLI tool that pulls data from Contentful and turns it into markdown files for Hugo and other static site generators. It also includes an express server that can be used for local development and content previews
https://github.com/ModiiMedia/contentful-hugo
A CLI tool that pulls data from Contentful and turns it into markdown files for Hugo and other static site generators. It also includes an …

Contentful からのデータ連携が非常に快適にできたこと、そしてこれまで慣れ親しんだ Hugo の知識が活かせることから、課題解決のスピード感との兼ね合いで再び Hugo に鞍替えしました。

これら一連の検証を経て、

  • Contentful でコンテンツを管理
  • サイトジェネレートは Hugo で実施
  • 生成されたサイトは Netfly にデプロイして配信

という当初やりたかった一連のフローを実現できたので満足しています。 contentful-hugo については、別の記事でまとめられたらと思います。

その他参考情報

MarkdownをめてHeadlessCMSにする意味

一人で書く分にはMarkdownのほうがいい。慣れ親しんだエディタがあれば編集もしやすい。差分管理もGitで問題ない。しかし画像メンテだけが非常に面倒なのが正直な感想。

HeadlessCMSについて

Nextのドキュメントに以下のサービスリストがありました。Headless CMSってどれを選べばいいんだろうか?と思ったときに、ひとつの目安になると思います。

  • WordPress
  • Sanity
  • TakeShape
  • Prismic
  • Contentful
  • Strapi
  • Agility CMS
  • Cosmic
  • ButterCMS
  • Storyblok
  • GraphCMS
  • Kontent
  • Ghost
  • Blog Starter

ほか、Gatsby目線での人気CMSリストがあるのでこちらも参考に。 https://www.gatsbyjs.com/docs/how-to/sourcing-data/headless-cms/#popular-cmss

なお microCMS という日本製のサービスもあります。microCMS|APIベースの日本製ヘッドレスCMS

Contentfulに関する事例は、一つの参考情報として以下の記事があります。

Contentful vs microCMS vs GraphCMS

次に、いくつかあるHeadlessCMSの候補の中からなぜContentfulを採用するに至ったかです。 具体的には以下のような候補がありました。
- Contentful
- microCMS
- GraphCMS

これらの中からContentfulを選んだ理由は、(料金)×(機能)で考えたときのコストパフォーマンスが最大になる選択肢だったからです。

https://engineer.crowdworks.jp/entry/2020/04/10/174736

Hugo で困るシーン

結果的にHugoを推す形になっていますが、サイトデザインをしていて困るシーンも度々発生します。 何らかの解決策はあるのですが、WordPressのように標準機能・プラグインで1クリックポチッとでは済まないこともあります。

  • 記事の人気アクセスランキングを作りたい
  • はてなブログのようにページリンクをオシャレにしたい(ブログカード)

これらの根本は、SSGで生成されたサイトは動的プログラムではない(静的ページである)ため、アクセス数に応じて集計したり、任意のタイミングで他ページのOGP情報を取得できないといった、まさにCMSの強みといっていた部分の正反対でSSGの弱みになります。こういう点が、いいところどりをできる Next.js であれば解決できる部分もあるのでしょうね。

解決策がないというわけではなく、ちょっと(かなり?)面倒くさいという感じです。 今回は解決策まで言及はしていませんが、機会があれば記載したいと思います。もちろん、調べれば出てくる情報も多いです。