きっかけ
先日、会社の人にこの動画が面白いかもねと教えてもらいました。
こちらの動画はタイトルの通り、Gatsby.jsとNext.jsのどちらがより良いSSG(=Static Site Generation)ができるのか?要するに静的サイトをいい感じに作れるのか?という話がされています。
この中で動画の主は最後に僕だったらNext.js使うね。という感じの発言をされており(多分)、全体的にNext.jsの方が使いやすいよ〜という感じで話されていました。(英語力的に多分)
というわけで本当にそうなのかブログレベルですが試してみたので、そのときに感じた点などを共有したいと思います。
設計思想の違い
まずは、両者の根本的な設計思想の違いについて触れたいと思います。
Gatsby.js
Gatsby.jsは機能拡張に対してプラグインを用いたアプローチをとっています。例えばマークダウンファイルを読み込む、外部からデータをとってくる。など、様々な用途に対応したプラグインが用意されています。これは自身の用途に合致していれば、簡単にやりたいことができる反面、少しでもそのプラグインが提供している機能以外のことをしようとした場合や、そもそもプラグインでは対応できないようなことをしようとすると、今までブラックボックスだった部分を読み解かなければならなくなるので途端に面倒になりがちです。
また、個人的にはGatsby.jsで少し変わったことをしようとすると何かにつけて必要なGraphQLにnodeを作るためにGatsby-node.jsに書かなければならないコードはドキュメントを読んでも読み解きづらいなと感じますし、ES6の構文が使えないので面倒だなと思います。
Next.js
対してNext.jsは最低限必要な機能だけを提供します。必要な機能は自分で作ろう!というBarebones Approachをとって作られています。これはGatsby.jsと比べ、自由度が高くコードが書けるかつ、自分で書く分何をやっているのか把握できるのでやりたいことに対して柔軟に対応できると言えると思います。しかしそれは個人のスキルに依存する要素が大きいと言い換えることもできるでしょう。
コードはNext.jsの方が書きやすい
個人的にはNext.jsの方がコードは書きやすいなという印象です。Gatsby.jsでは最初はGraphQLのクエリ文が書かれているのも慣れないでしょうし、エラーが出てもブラックボックス部分が大きくいったいどこに問題があるのかわかりづらいという印象があります。Next.jsは上で述べたように自分で書く必要がある分、何が行われているのかjsの知識(React+ α)だけで追いやすく、エラーに対しても素早く対応できることが多いです。
画像の最適化周りはGatsby.jsの方がやりやすい
Gatsby.jsではGatsby-imageというプラグインが画像をとてもいい感じにマネジメントしてくれます。具体的には
- placeholderとして荒い画像を最初に読み込んでおく。
- スマホサイズ、デスクトップサイズなどの数種類の画像を自動的に生成し、デバイスによって適切なサイズの画像を自動的に読み込んでくれる。
- intersection Observer APIを用いてその画像が画面に入ったとき、などのイベントをとって、グッドなタイミングで読み込みを開始してくれる
- そしてそれらをブラーエフェクトなどをかけていい感じに表示してくれる。
などです。これがなかなか強力な機能なので、Next.jsでも実装しようとしました。
しかし、Next.jsには画像のパスをもとに、荒い画像を返してくれるnpm moduleなどはあるものの、Gatsby.jsレベルの機能を実装しようと思うと、かなり手間がかかりそうでした。それだったらGatsby.jsで少し面倒でもクエリ文を書き〜とする方が簡単だと思いました。
パフォーマンス(スピード)はGatsby.jsの方が簡単に出せるような気がする
これに関しては全く同じサイトを作ったわけではないのでやっていることの違いや、僕のコードの問題もあるかもなので一概に「Gatsby.jsの方がパフォーマンスが出る」とは言えないですが、何も考えないでコードを書いてもパフォーマンスがいいのはgatsby.jsという印象です。Gatsby.jsでは、import
しておいて使っていなかったり定義しておいて使っていない変数、定数があったりした場合、エラーが出るので、そういった面でコードの質がある程度担保されているからかな?と思っています。
まとめ
まとめるとNext.jsの方がコード書きやすいけどGatsby.jsの方がパフォーマンスは出しやすい。みたいな感じになると思います。
しかし、そもそもNext.jsは静的サイトジェネレーターではないので、サービスを作るならNext.js、静的なサイトでいいならGatsby.jsを使うのがベストだと思います。