Closed7

heic2anyの遅延読み込み

gtcagtca

Next.jsで作ったWebアプリのパフォーマンスが悪いなぁと思っていろいろ調べてみた。

npm run buildしたときのFirst Load JSが600kBとかになっていて、結構重くなっていた。
@next/bundle-analyzerというものがあるらしいので、それでまずはビルド時のバンドルサイズを確認する。

導入方法はこちら。
https://nextjs.org/docs/app/building-your-application/optimizing/package-bundling

gtcagtca

npm run analyzeすると、3つのタブが立ち上がる。nodejs.htmlとedge.htmlとclient.html。クライアント側で読み込まれるjsファイルはclient.htmlかな?

heic2anyがめちゃくちゃ重い。。
mantineも結構重い。

gtcagtca

heic2anyはiPhoneで撮影した画像フォーマットであるHEIC/HEIF形式の画像をJPEGとかPNGとかに変換したい時に使うライブラリ。

mantineはReactベースのUIコンポーネントライブラリ。

gtcagtca

heic2anyは以下のように変更。

Before

useEffect(
  if (typeof window !== "undefined") {
    const heic2any = require("heic2any");
    // その後の変換処理
  }
)

After

useEffect(
  if (typeof window !== "undefined") {
    (async () => {
      const heic2any = (await import("heic2any")).default;
      // その後の変換処理
    })()
  }
)

こうすることで遅延読み込みになって、この処理が行われるまでは読み込まれないようになる。

この対応を入れた後、@next/bundle-analyzerでバンドルサイズを見たときはclient.htmlには特に変化はない。ただnpm run buildしたときのFirst Load JSは200kBくらいになって確かに軽くなっていた。

またブラウザの開発ツールのNetworkタブで確認したところ該当部分が呼ばれるまではheic2anyの読み込みが発火しないことも確認できた。

gtcagtca

mantineの方は使っていないコンポーネントもバンドルに含まれてるっぽかったので、実際に使っているコンポーネントだけ読み込めないか情報を探してみた。

結論、こういうNext.jsのオプションがあるようだった。

https://nextjs.org/docs/app/api-reference/config/next-config-js/optimizePackageImports

これを入れると実際に使っているモジュールだけ読み込みしてくれるらしい。
next.config.jsを編集する。

const nextConfig = {
  ...
  experimental: {
    optimizePackageImports: ['@mantine/core', '@mantine/hooks'],
  },
  ...
}
...

@next/bundle-analyzerで確認すると不要なコンポーネントは除外されていた。また、First Load JSのサイズもちょっとだけ小さくなっていた。

gtcagtca

ダイエット成功。外部ライブラリを導入する時にはそのライブラリのサイズも意識しないとパフォーマンスに影響が出ることを学んだ。

このスクラップは2025/03/07にクローズされました