javascript json 103 lines · 4 tabs

Next.js bundle analyzer for targeted performance work

Shared by codesnips Jan 2026
4 tabs
const withBundleAnalyzer = require('@next/bundle-analyzer')({
  enabled: process.env.ANALYZE === 'true',
  openAnalyzer: true,
});

/** @type {import('next').NextConfig} */
const nextConfig = {
  reactStrictMode: true,
  productionBrowserSourceMaps: process.env.ANALYZE === 'true',
  experimental: {
    optimizePackageImports: ['lodash-es', 'date-fns', '@mui/icons-material'],
  },
  webpack: (config, { isServer }) => {
    if (!isServer) {
      config.optimization.moduleIds = 'deterministic';
    }
    return config;
  },
};

module.exports = withBundleAnalyzer(nextConfig);
4 files · javascript, json Explain with highlit

This snippet shows how to turn @next/bundle-analyzer from a one-off manual inspection into a repeatable, enforced part of a performance workflow. The idea is that measuring bundle size is only useful if it is done consistently and compared against a budget, so the setup wires analysis into the normal build and then fails CI when a route exceeds its allowed first-load JS.

In next.config.js, withBundleAnalyzer wraps the base config and is gated on process.env.ANALYZE. This matters because the analyzer plugin has overhead and produces HTML reports that should not run on every production build. The config also enables optimizePackageImports for a couple of heavy libraries, which lets Next.js rewrite barrel imports into deep imports so tree-shaking actually removes unused code — one of the most common reasons a route bundle balloons.

The analyze npm script in package.json sets ANALYZE=true and runs the build, which is what a developer runs locally to open the treemap and see which modules dominate a chunk. Reading that treemap is how the pattern starts: it reveals whether a large dependency is being pulled into a shared chunk or into a single route, which tells the engineer whether to lazy-load, swap the dependency, or split the import.

The checkBudgets.js script closes the loop. Next.js writes .next/build-manifest.json and app-build-manifest.json describing which JS files each route loads; checkBudgets sums those file sizes per route, compares them against budgets.json, and exits non-zero on any violation. The budgets map keys off route patterns so different pages can carry different limits — a marketing landing page should be far lighter than a data-heavy dashboard.

The trade-off is that byte budgets are approximate: gzip and shared-chunk deduplication mean the raw file sum overstates real transfer size, so budgets should be tuned with headroom rather than treated as exact. Still, this approach catches regressions early, keeps the treemap honest, and gives a concrete number to defend during code review. A developer reaches for it once ad-hoc profiling stops scaling across a team.


Related snips

Share this code

Here's the card — post it anywhere.

Next.js bundle analyzer for targeted performance work — share card
Link copied