せっかちだからJamstackな静的サイトを約10秒で更新するよ(Gatsby Cloud & Contentful)

2021.05.22

どうも、ベルリンオフィスの小西です。

Jamstackな静的サイトでは(当たり前ですけど)サイトを公開する前に静的ページをビルドする時間がかかるわけなのですが、「めっちゃ急いでるので1秒でも速くサイトを更新したい」「編集中の記事を秒でプレビューしたいのだが」というニーズがありました。

今回このビルド時間の問題を、Gatsby Cloudの機能 Incremental Build, Cloud Build, そして Preview Builds を使い、約10秒まで短縮したいと思います。いずれの機能もJamstackサイト導入に際して大きなインパクトがある機能だと思ってます。

前提

  • フロントをGatsby(Version 2.20.4 以降)、ホスティングにGatsby Cloud (ビルドプランでスタンダードプラン以上)を使っている
    • ちなみに今回のビルド速度の検証はスタンダードプランで試しています。

Gatsbyのビルド機能の整理

Gatsbyのややこしい点として、サイトのビルドオプションが複数存在します。現状覚えておくのは下記3つかと思います。

1. Incremental Build

Gatsbyではデータソースに変更があった際(例えばバックエンドのContentfulで一記事だけを更新した場合でも)、サイト全体をビルドし直す仕組みになっています。

これによりビルド時間が積み上げ式に増えていく問題がありました。

Incremental buildではこの問題を解決するため、データソースで変更があった際、必要なHTMLのみを再ビルドすることが可能になりました。

.cachepublic ディレクトリの差分を利用するため、ホスティング側もこれに対応している必要があり、現状ではGatsby Cloudの一機能として、もしくはNetlifyで専用プラグイン netlify-plugin-gatsby-cache を利用したビルドを行う(Netlify公式ブログ)ことで利用が可能です。

2. Cloud Build

データソースとなるCMS側で変更があった際、そもそもGatsbyの全てのビルドプロセスを実行せず、必要最低限の処理のみを実行することで、Incremental Buildよりさらに高速なデプロイが可能になっているのがCloud Buildです。

また、いくつかのビルドプロセスを並行化することでもビルドの高速化を図っています。具体的にはgatsby-plugin-sharp のversion 2.4.0 以降を利用している場合の画像最適化などです。

Gatsby Cloudでのみ利用できる機能で、ビルドプランで[スタンダード]以上を契約する必要があります。

3. Preview Builds

Gatsbyでは、Contentfulなど特定のCMSと連携した場合に、CMS側での更新をトリガーに自動でプレビュー用のビルドを行ってくれます。プレビュー用のドメインが割り当てられており、本番とは違う環境変変数をセットして別のデータソースを使うこともできます。

機能的には上記のCloud Buildsと似ていて、不要なプロセスを極力排して高速なページ確認が可能になります。

例えばヘッドレスCMS側で一文字だけ編集した場合もフロントのビルド時間に待たされてしまうとか、Next.jsなどではプレビューのみサーバーサイドレンダリングするなどの手があると思いますが、Gatsbyでは悩みどころだったこの問題を、Preview Buildsは解決してくれます。

ちなみに上記のCloud Buildオプションの有無はこのPreview Buildsに影響は及ぼしません。

使ってみる & ビルド時間の検証結果

それでは上記で紹介した各ビルドオプションのビルド時間を検証していきます。

検証方法

今回ヘッドレスCMSとしてContentfulを使っています。Contentfulは無料プランのままでもOKです。

今回はContentfulから特定の一記事の1フィールドを編集した場合のビルド時間について見てみます。事前に記事は30記事ほど投稿していて、記事一覧と記事詳細ページがあるブログのような構成にしています。

Incremental Buildsの有効化

Gatsby側でデフォルトでONになっていますので、GatsbyのVersion3以降であれば、ユーザー側で特に何もする必要はありません。

Incremental Buildsのビルド時間

この時点でビルドが39秒かかりました。

キャッシュを読み込んで差分だけビルドしており、遅いわけではないのですが、それでも30秒以上はかかってしまいます。次のCloud Buildsでこれをさらに高速化します。

Cloud Buildsの有効化

[Site Settings] → [Builds](左サイドバー) → [Enable cloud builds] にチェックを入れます。

Cloud Buildsのビルド時間

ビルドがわずか5秒で完了しました。これは速い! デプロイを含めても12秒で更新が完了しています。

また、ビルドログは下記のような感じです。データソースであるContentfulからデータを取得し、クエリを書き直しているだけで、リポジトリからソースコードを引っ張ってきたり、CSS&JSのバンドルを作成したりといった処理は行われていないのがわかります。

Preview Buildsの有効化

先ほどのCloud Buildsは本番環境でのビルドに対する機能でしたが、Preview Buildsはプライベートなプレビュー生成をしてくれます。

Gatsby側でプロジェクトを作成する際にContentfulを連携するか、もしくはContetnful側でプラグインとして導入できます。個人的には前者のGatsby側からやってしまう方法がオススメです。Gatsbyのほうで、Contentful側の必要なAPIキーを作成してGatsby Cloudの環境変数に保存するところまでやってくれます。

Preview Buildsのビルド時間

毎回5秒未満で完了しています。速すぎ。これなら記事ページを見ながらの更新作業のストレスが大幅に低減されます。Preview Buildsの段階では本番環境に何の影響も与えませんのでご心配なく。このPreview環境に認証をかけることも可能です。

現時点での問題

コールドスタート問題

公式の説明では、24時間が経過するとビルドマシンがコールドスタート状態に移行するため、ビルド時間が長くなります。私のケースではコールドスタート状態だと 34 秒かかりました。

このコールドスタート問題は、本番ビルド、プレビュービルド、どちらにも発生するようです。

また、当然ながら更新された記事量によってもビルド時間は前後するほか、Gatsbyサポートによるとビルド時間を長くする要因はいくつかあるとのことです。

Contentful側でビルド完了を検知できない

上記で紹介した通り、ビルド時間は5秒未満で済む場合や状況によって30秒 ~ 1分かかることもありますが、現状、Contentful側でサイトビルドが完了したことを検知する方法がありません。

代替策として、本番環境でのビルド完了に関してはWebhooks機能を使い、Slackなどに通知を送ることが可能です(ただしPreview Buildsには今後対応予定とのことです)。

最後に

今回はスタンダードプランでしたが、Pro planであればビルドマシンのスペック自体がさらに向上するので、さらなる更新速度の向上が望めます。

Classmethodでは、Jamstackサイトの構築支援やContentfulの契約のご相談をしています。ご興味のある方はぜひ弊社までお問い合わせください。

参考記事

https://support.gatsbyjs.com/hc/en-us/articles/360053099253-Gatsby-Builds-Full-Incremental-and-Cloud