Masayan tech blog.

  1. ブログ記事一覧>
  2. Next.jsのアプリケーションでバンドルサイズを改善した話

Next.jsのアプリケーションでバンドルサイズを改善した話

公開日

環境

  • windows10
  • macOS Monterey 12.0.1
  • node 18.13.0
  • npm 8.19.3
  • React 18.2.0
  • Next.js 13.2.1
  • VsCode

この記事の内容

バンドルサイズを減少させることで、Next.jsアプリケーションのパフォーマンスを向上させようという話です。

具体的には、現状のバンドルサイズの確認ボトルネックの調査改善の手順となります

前提

next buildでビルド完了後、ページ単位でチャンクファイルが生成されチャンクファイルサイズの一覧が出力されます

右側に表示されているFirst Load JSは、ページにアクセスした際にダウンロードされるアセットのサイズなので、このサイズが大きいほどパフォーマンスが低下することになります。

また、First Load JSは色分けされ、緑、黄色、赤色で表示され、緑が最も高パフォーマンスということになっています

バンドルサイズの解析

ビルド時に表示されるチャンクのサイズだけでは調査が難しいので、別途専用のライブラリをインストールして、詳細を解析できるようにします。

npm install @next/bundle-analyzer

next.config.mjsでimportし、環境変数がanalyze: trueの場合、バンドルアナライザーの処理が実行されるように指定します

参考:バンドルアナライザーのESM形式のサポート

import analyze from '@next/bundle-analyzer'


const withBundleAnalyzer = analyze({
  enabled: process.env.ANALYZE === 'true',
  defaultSizes: 'gzip',
})


/** @type {import('next').NextConfig} */
const nextConfig = {
  reactStrictMode: true
}


export default withBundleAnalyzer(nextConfig)

.env.analyze

ANALYZE=true

npm scripsに実行用コマンドを登録

{
  "scripts": {
   .. 
    "analyze": "env-cmd -f .env.analyze next build"
  },

実行します

npm run analyze

実行後、以下3種類のhtmlが生成され、アクティブなブラウザに自動で新規タブに表示されます

  • .next\analyze\client.html
  • .next\analyze\edge.html
  • .next\analyze\nodejs.html

このうち、client.htmlはブラウザ側で使用されるJs、Cssのサイズが表示されており、その面積が大きいほどバンドルサイズ肥大化の原因になっている可能性が高いです。

特に、このlottie.js(react-lottie)はアニメーション用のライブラリであり、ほかのライブラリと比べバンドルサイズが大きいことが見て取れます。

いずれかのバンドルの上にマウスを置くだけで、その統計が表示されます。各バンドルの統計サイズ、解析済みサイズ、Gzip 圧縮サイズ、およびバンドルのファイルパスを確認できます。

サイズの種類

  • Stat size
    アプリを実行するためにブラウザがダウンロードして実行する必要があるJavaScriptのサイズ
  • Parsed size
    JavaScript実行後に Web ブラウザーで占有されるメモリの量
  • Gzipped size
    アプリを実行するためにブラウザがダウンロードして実行する必要があるJavaScript(Gzipアルゴリズムを使用して圧縮済み)

エディター上から確認すると、ライブラリ自体のサイズもかなり大きいことがわかります。

バンドルサイズの改善

まず、同じような問題に直面しているケースを探しその解決方法を探ります。探したところ、react-lottieの軽量版である、react-lottie-liteというライブラリがあることを知りました。

https://www.npmjs.com/package/react-lottie-light

ただ、このライブラリは現在メンテナンスされていないようで、Reactのversionも15で止まっていました。

https://github.com/chenqingspring/react-lottie

そのため、react用のlottieライブラリの使用を断念し、lottie-web-light(lottie-webの軽量版)を使いつつ、reactの部分はオリジナルで実装するという方法を採用しました。

https://www.npmjs.com/package/lottie-web-light

https://github.com/chenqingspring/react-lottie/issues/139

※lottie-web-lightは軽量版なので、軽量版では実現できない複雑な処理が必要な要件がある場合は別の解決法を検討する必要があります。

改善結果

Stat sizeが約600kb→200kbまで減少しました。

Before

After

その他のヒント

未使用のライブラリが残ったままになっていることも、アプリケーション全体のサイズが肥大化する原因の一つです。

以下のコマンドを実行することで、未使用のライブラリをチェックすることが可能です。

※ただし、検知された結果は必ずしも正確ではないので、それらを 1 つずつアンインストールし、アプリを再実行して、期待どおりにビルドされ動作することを確認することをお勧めします。

npx depcheck

まとめ

いかがでしたでしょうか。Next.jsのアプリケーションでバンドルサイズを改善するための具体的な手順と改善例について紹介しました。バンドルサイズの肥大化はアプリケーション全体のパフォーマンスに影響を及ぼすため、@next/bundle-analyzerを使用して調査/改善を行う必要があります