Tech系サービスやガジェットの使い心地、自分の作業環境、資産運用について気が向いたときに記録を残しています。

記事内のAmazonアソシエイト適格販売及び、Google Adsenseでお小遣いを得ています。

NetlifyでGatsby.jsのIncremental Buildが使えるようになったのでビルド時間短縮を検証してみた

Gatsby.jsのIncremental BuildがNetlify上でBeta版として利用できるようになりました

www.netlify.com

これは、本来は毎回リポジトリ全ページをビルドするGatsbyのビルドを、前回ビルド時のキャッシュを利用して更新が入ったページのみ追加でビルドして更新のないページはそのままにするというもので、大きなWEBサイトで毎回長いビルド時間をデプロイのために費やす必要をなくすためのものです。

ローカルサーバー作成時には使えないので、開発時は今のままです。

まずは、本当に短縮されるのか比較的サイズの小さいリポジトリで検証してみます。

※Netlifyはフリープランです

リポジトリ

利用のためのコード修正と、Netlifyの設定変更を行います。

1. Netlifyセッティング

Netlifyのビルドプラグインを有効にします。これだけはWEBコンソールからの設定が必要です。

次にnelify.toml末尾に設定を追加します。

[[plugins]]
  package = "netlify-plugin-gatsby-cache"

ProductionのContextだけに含めるなどの設定ができると面白いのですが、今回は未検証です。

2. npm scriptの更新

ビルド用のnpm scriptにIncremental Build用の環境変数を追加します。

  "scripts": {
    "build": "GATSBY_EXPERIMENTAL_PAGE_BUILD_ON_DATA_CHANGES=true gatsby build",
    ...

buildコマンドに gatsby clean を入れているとキャッシュを消去してしまうので、利用している場合は使わないようにします。

ページごとにどのページが新しくビルドされたのか知りたい場合は、 --log-pages オプションを末尾に追加します。

あとはGatsby.jsを最新版に更新すれば準備はOKです。

ログから結果確認

pluginを追加したことで、見慣れない出力が出てきます。

8:42:23 PM: ┌─────────────────────────────┐
8:42:23 PM: │        Netlify Build        │
8:42:23 PM: └─────────────────────────────┘
8:42:23 PM: ​
8:42:23 PM: ❯ Version
8:42:23 PM:   @netlify/build 0.4.26
8:42:23 PM: ​
8:42:23 PM: ❯ Flags
8:42:23 PM:   mode: buildbot
8:42:23 PM: ​
8:42:23 PM: ❯ Current directory
8:42:23 PM:   /opt/build/repo
8:42:23 PM: ​
8:42:23 PM: ❯ Config file
8:42:23 PM:   /opt/build/repo/netlify.toml
8:42:23 PM: ​
8:42:23 PM: ❯ Context
8:42:23 PM:   production
8:42:23 PM: ​
8:42:23 PM: ❯ Installing plugins
8:42:23 PM:    - netlify-plugin-gatsby-cache
8:42:42 PM: ​
8:42:42 PM: ❯ Loading plugins
8:42:42 PM:    - netlify-plugin-gatsby-cache@0.2.1
8:42:42 PM: ​
8:42:42 PM: ┌────────────────────────────────────────────────────────┐
8:42:42 PM: │ 1. onPreBuild command from netlify-plugin-gatsby-cache │
8:42:42 PM: └────────────────────────────────────────────────────────┘
8:42:42 PM: ​
8:42:42 PM: No Gatsby cache found. Building fresh.
8:42:42 PM: ​

プラグインの利用と、Incremental build用のキャッシュが存在しないことを出力しています。

次に、Markdownファイルを1つ修正したコミットのデプロイ結果を見ます。

8:51:30 PM: ┌────────────────────────────────────────────────────────┐
8:51:30 PM: │ 1. onPreBuild command from netlify-plugin-gatsby-cache │
8:51:30 PM: └────────────────────────────────────────────────────────┘
8:51:30 PM: ​
8:51:30 PM: Found a Gatsby cache. We’re about to go FAST. ⚡️
8:51:30 PM: ​
8:51:30 PM: (netlify-plugin-gatsby-cache onPreBuild completed in 255ms)

前回のビルド結果がキャッシュとして使われていることが通知されました!

肝心のビルド時間を確認してみます。

f:id:gensobunya:20200516120617p:plain

201秒→164秒へ約20%の削減達成!このサイトはHTML15枚、サムネイルが99枚ビルドされた結果です。

サイズの大きいサイトで試す

より効果を実感するための、数年間運用しているブログをビルドしてみます。

HTMLページは222ページ、サムネイルは2500枚程度なのでおおよそ15倍の規模です。

f:id:gensobunya:20200516122120p:plain

全体で652秒から、1ページのみの更新だけのビルドでは274秒まで短縮されました!すごい!

ただ、その後の netlofy.toml をビルドした結果で377秒かかっているのが気になります。理論上は1ページも更新されていないのだから、もっと速いはず…

ビルド時間内訳の確認

3回のビルド時間の内訳を確認してみます。

  • Build ready to start ~ Netlify Build
  • Netlify Build ~ onPostBuild command from netlify-plugin-gatsby-cache
  • onPostBuild command from netlify-plugin-gatsby-cache ~ Site is Live

これらの3つに分類して時間を比較します。

イメージ起動~npm install Gatsby build Post processing
初回ビルド 9:09:28~9:12:16 9:12:16~9:17:37 9:17:37~9:20:31
1ページ更新 9:20:54~9:21:51 9:21:51~9:23:34 9:23:34~9:25:31
設定ファイル更新 9:27:52~9:29:10 9:29:10~9:31:23 9:31:23~9:34:13

秒数に直します

(sec) イメージ起動~npm install Gatsby build Post processing
初回ビルド 168 321 174
1ページ更新 57 103 97
設定ファイル更新 78 133 170

考察

Dockerイメージ起動とnpm installの時間が大幅に短縮されているのは、Netlifyの内部処理によるものと推測できます。これだけで2分ほど短縮されているのですが、実際の更新がこれほど頻繁に走ることはないので実際はこの120秒前後はIncremental Buildによって、日々のデプロイで短縮される時間ではないと推測できます。

Gatsbyのビルド時間は1/3ほどに短縮されています。これは素晴らしい効果。一方で1ページも更新していない際に30%ほど長時間化している点はNetlifyのコンテナ環境によるものなのか、Incremental Buildの要改善点なのかはこれからの更新やコミュニティをウォッチする必要がありそうです。

Post processingの時間差は…謎です。Incremental Buildの影響でMinifyingする必要があるJS,CSSがなくなっているので1ページだけ更新しているビルドはこれらのプロセスがスキップされており、その分2~3分の短縮がされています。

9:18:30 PM: Starting post processing
9:18:31 PM: Minifying js bundle
9:18:34 PM: Minifying js bundle
9:19:15 PM: Minifying js bundle
9:20:04 PM: Finished processing build request in 10m26.801042671s
9:20:20 PM: Minifying js bundle
9:20:31 PM: Post processing done
9:20:31 PM: Site is live

↓

9:24:20 PM: Starting post processing
9:25:30 PM: Post processing done
9:25:31 PM: Site is live
9:25:50 PM: Finished processing build request in 4m54.572851706s

一方で、設定ファイル更新したビルドは謎の2分間がPost Processingに費やされています。

9:32:21 PM: Starting post processing
9:33:37 PM: Finished processing build request in 5m42.65207949s
9:34:12 PM: Post processing done
9:34:13 PM: Site is live

これ以上このログから何が起きたのか追うことは出来ませんが、まだβ版機能ですので不具合が残っているのでしょう。

コミュニティでも不可解なビルド時間に対する議論が起きているので、GAまでの改善を期待します。

community.netlify.com

これは良いんだけどCDNのレスポンスがポンコツ化したのなんとかしてくれないかな…