Automating Next.js Bundle Size Monitoring

10 min read
📝 1028 words
Automating Next.js Bundle Size Monitoring

Bundle size can creep up silently in a Next.js app, so automating analysis on every GitHub push is a solid move. With Next.js 14 and GitHub Actions, you can set up a pipeline that:

  1. Builds your Next.js app

  2. Analyzes bundle size (server + client)

  3. Reports results back to PRs or commits

  4. Use @next/bundle-analyzer for local bundle inspection

For Next.js, you can use the @next/bundle-analyzer package to analyze your bundle size.

First, install the package:

npm install @next/bundle-analyzer --save-dev

In my next.config.ts file, I added the following code to enable the bundle analyzer:

// eslint-disable-next-line @typescript-eslint/no-require-imports
const withBundleAnalyzer = require('@next/bundle-analyzer')({
 enabled: process.env.ANALYZE === 'true',
})

module.exports = withBundleAnalyzer(nextConfig);

and in package.json, I added the following script to run the analyzer:

"scripts": {
   "analyze": "cross-env ANALYZE=true next build"
}

Now you can run the following command to build your project and analyze the bundle size:

npm run analyze

You will see a visual representation of your bundle size in the terminal or in a browser window.

something like this:


Route (app)                                 Size  First Load JS  Revalidate  Expire
┌ ○ /                                    41.8 kB         179 kB
├ ○ /_not-found                            999 B         103 kB
├ ○ /about                               2.54 kB         113 kB
├ ○ /blog                                  133 B         102 kB
├ ○ /contact                             9.94 kB         117 kB
├ ○ /education                             62 kB         243 kB
├ ○ /experience                          23.5 kB         210 kB
├ ○ /gallery                               133 B         102 kB
├ ○ /newsletter                            133 B         102 kB
├ ○ /portfolio                           22.1 kB         139 kB          1h      1y
└ ○ /resources                             133 B         102 kB
+ First Load JS shared by all             102 kB
  ├ chunks/255-0009d5863092a8cd.js       45.5 kB
  ├ chunks/4bd1b696-409494caf8c83275.js  54.2 kB
  └ other shared chunks (total)          2.21 kB

You can see the size of each route and the total size of the JavaScript loaded for each route.

The First Load JS column shows the total size of JavaScript that needs to be loaded for the initial page load. The First Load JS shared by all section shows the size of JavaScript that is shared across all routes.

What if our bundle grows again ? If there was a way to prevent that and increase awareness of the bundle size during development itself ?

Bundle Size Monitoring

We can check the bundle size during development using tools like size-limit.

For example, to use size-limit, you can follow these steps:

  1. Install size-limit and its dependencies:
npm install size-limit --save-dev

For calculating the size of different types of files, you may also need to install additional plugins. For example, to analyze JavaScript files, you can install:

Update your package.json dependencies accordingly.

"devDependencies": {
    "size-limit": "^11.2.0",
    "@size-limit/file": "^11.2.0",
    "@size-limit/time": "^11.2.0",
    "@size-limit/webpack": "^11.2.0",
    "@size-limit/webpack-why": "^11.2.0"
}
  1. Add a size-limit configuration to your package.json:
"size-limit": [
  {
    "path": "dist/index.js",
    "limit": "100 KB"
  },
  // Add more entries as needed
]
  1. Add a script to your package.json to check the bundle size:
"scripts": {
  "size": "npm run build && size-limit --why" // why for webpack analysis
}

Now, you can run the size script to check the bundle size:

npm run size

You will get result something like this:

  Package size limit: 100 KB
  Size: 85 KB with all dependencies, minified and gzipped (84 KB)
  Time: 1.5 s to load and parse (1.4 s)

If the bundle size exceeds the limit, the command will fail and display an error message.

Using Plugins for More Detailed Analysis

Size limit supports various plugins to analyze different types of files. For example, you can use the @size-limit/webpack plugin to analyze your Webpack bundle.

You can refer to the Size Limit documentation for more information on available plugins and how to use them.

Using Size Limit with Next.js

You can use size-limit with Next.js by specifying the paths to your built files in the size-limit configuration.

eg. configuration in package.json

For pages router :

"size-limit": [
  {
    "name": "Home Page",
    "path": ".next/static/chunks/pages/index.js",
    "limit": "150 KB"
  },
  {
    "name": "About Page",
    "path": ".next/static/chunks/pages/about.js",
    "limit": "100 KB"
  }
]

For app router :
```json
"size-limit": [
  {
    "name": "Home Page",
    "path": ".next/static/chunks/app/index.js",
    "limit": "150 KB"
  },
  {
    "name": "About Page",
    "path": ".next/static/chunks/app/about.js",
    "limit": "100 KB"
  }
]

You will get the size of each page and whether it exceeds the specified limit when you run the size script.

  Homepage
  Size limit:   150 kB
  Size:         10.14 kB with all dependencies, minified and gzipped
  Loading time: 199 ms   on slow 3G
  Running time: 12 ms    on Snapdragon 410
  Total time:   210 ms
  
  About Page
  Size limit:   150 kB
  Size:         192 B  with all dependencies, minified and gzipped
  Loading time: 10 ms  on slow 3G
  Running time: 35 ms  on Snapdragon 410
  Total time:   45 ms
  
  Project Page
  Size limit:   150 kB
  Size:         2.8 kB with all dependencies, minified and gzipped
  Loading time: 55 ms  on slow 3G
  Running time: 11 ms  on Snapdragon 410
  Total time:   66 ms
  
  Blog Page
  Size limit:   150 kB
  Size:         99 B   with all dependencies, minified and gzipped
  Loading time: 10 ms  on slow 3G
  Running time: 18 ms  on Snapdragon 410
  Total time:   28 ms
  
  Contact Page
  Size limit:   150 kB
  Size:         1.45 kB with all dependencies, minified and gzipped
  Loading time: 29 ms   on slow 3G
  Running time: 10 ms   on Snapdragon 410
  Total time:   39 ms
  
  Gallery Page
  Size limit:   150 kB
  Size:         99 B   with all dependencies, minified and gzipped
  Loading time: 10 ms  on slow 3G
  Running time: 11 ms  on Snapdragon 410
  Total time:   21 ms

Automating Bundle Size Checks with GitHub Actions

You can automate the bundle size checks using GitHub Actions. Heres a simple workflow that runs the size check on every push to the main branch:

We can use the following Size Limit Action GitHub Actions workflow to automate the bundle size check:

  • Add the following action inside .github/workflows/size-limit.yml
name: "size"
on:
  pull_request:
    branches:
      - master
permissions:
  pull-requests: write
jobs:
  size:
    runs-on: ubuntu-latest
    env:
      CI_JOB_NUMBER: 1
    steps:
      - uses: actions/checkout@v1
      - uses: andresz1/size-limit-action@v1
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}