blog

備忘録です。雑多な内容を書きます。

"next export" でも画像最適化したい!

Next.jsの next/image はデフォルトではサーバーサイドで画像最適化するので、 next export で静的サイトとして利用したい場合、画像最適化を無効化するか、 custom で指定する必要がある。

9月にリリースされた Next.js 12.3でImage Optimizationを無効化するオプションがStableで利用できるようになったが、画像最適化は行われない……。

ビルド時に画像最適化を行ってくれる next-image-export-optimizer というライブラリがあり、これを使ってみたのでメモ。

www.npmjs.com

next.jsで画像最適化をする意味

環境

一応一通りセットアップし直してみたコードをGitHubに置いている。*1

github.com

  • "next": "13.0.6"
  • "react": "18.2.0"
  • "next-image-export-optimizer": "1.0.1"

セットアップ

基本的にはREADMEを読めばだいたい分かるが、 next.config.js に設定を追加し、 next/imagenext-image-export-optimizer に差し替えるだけで動作する。

srcsetが生成されたスクリーンショット。
srcsetが生成されている。

注意点としては、デフォルトではblur imageが生成され、小さめの画像を読み込む→ぼやけさせるフィルターをかける→読み込みが終わったら一瞬画像が消えたあと、完全な画像に差し替える、という挙動になっている。*2

ここはアプリケーションの要件によると思われるが、 placeholder="empty" を入れることで上記の挙動を抑制できる。

デフォルトのplaceholderの挙動

また、 images.imageSizes などで画像サイズのリストを指定するが、指定したサイズの数だけ画像が生成されるので、画像枚数が多いとビルド時間がどんどん遅くなる。

当たり前だがハマったポイントとして、 unoptimized: true になっていた場合は最適化されない。

画像が増えるほどビルドが遅くなる問題

ビルド時に画像最適化するため、画像枚数が多くなるほどビルド時間が増えていき、デプロイ時間がどんどん長くなる。
最適化済みの画像をコミットするという方法もあると思うが、バイナリファイルが増えすぎるのはちょっと嫌な気持ちもあるので、キャッシュすることで回避した。

雑にやっているので、 public/images 以下をまるごとキャッシュしている。チェックアウト後に public/images を上書きすると本来の画像が使えないので、 actions/checkout 前に行っている。

github.com

まとめ

基本的には next/image のインポートを差し替えれば使えるので、サクッと最適化したいときに良かった。

余談

記事を書いている途中で気付いたが、 next-export-optimize-images というライブラリもあり、こちらも結構良さそう。
こちらに移行するかも

www.npmjs.com zenn.dev

また、この記事は本業のアドベントカレンダー用に書いた記事だった。

qiita.com

*1:GitHub Pagesにデプロイしているが、パスの問題があるので正しく動作していない。関連Issueはすでに立ってそうだった。

*2:デベロッパー ツールを使ってネットワーク速度に制限をかけるとわかりやすい