Next.js Performance Configuration
Next.js Performance Configuration
This page documents the recommended next.config.ts configuration for SaaS Factory projects. A bare empty export — export default {} — leaves significant performance on the table. The sections below cover each optimization area, why it matters, and how to apply it.
1. Package Import Optimization (experimental.optimizePackageImports)
Why It Matters
Some npm packages export a large number of named exports from a single entry point. Without hints to the compiler, the entire package can end up in the client bundle even if only a fraction of its exports are used.
lucide-react is the most impactful offender in the current stack: it ships 563 icons (~600 KB raw). Using even one icon without optimizePackageImports can cause the full icon set to be included.
Configuration
// next.config.ts
import type { NextConfig } from 'next';
const config: NextConfig = {
experimental: {
optimizePackageImports: [
'lucide-react',
'date-fns',
'@dnd-kit/core',
'@dnd-kit/sortable',
'@dnd-kit/utilities',
],
},
};
export default config;
Estimated Impact
lucide-reactalone: −100–200 KB from the client bundle after tree-shaking.date-fns: moderate savings depending on how many locale/format helpers are imported.@dnd-kit/*: minor savings; included for consistency.
2. Bundle Analyzer (@next/bundle-analyzer)
Why It Matters
Without a bundle analyzer wired into CI, bundle size regressions go undetected until they affect real users. The analyzer generates a visual treemap of every module in the bundle, making it easy to spot unexpected large dependencies.
Installation
npm install --save-dev @next/bundle-analyzer
Configuration
// next.config.ts
import type { NextConfig } from 'next';
import withBundleAnalyzer from '@next/bundle-analyzer';
const config: NextConfig = {
// ...other options
};
export default withBundleAnalyzer({
enabled: process.env.ANALYZE === 'true',
})(config);
Running the Analyzer
ANALYZE=true npm run build
This opens an interactive treemap in your browser. Add a CI step that runs the build with ANALYZE=true and archives the output for size comparison across releases.
3. Image Format Configuration
Why It Matters
Next.js's built-in Image Optimization API can serve modern image formats to browsers that support them. avif offers the best compression ratios; webp is the widely-supported fallback. Without explicit configuration, Next.js does not serve these formats.
Configuration
const config: NextConfig = {
images: {
formats: ['image/avif', 'image/webp'],
},
};
Notes
avifencoding is more CPU-intensive at build time. For image-heavy pages, consider caching strategies or on-demand ISR.- The
formatsarray is ordered by preference; browsers that supportavifwill receive it first.
4. Production Console Removal (compiler.removeConsole)
Why It Matters
console.log, console.debug, and console.warn calls left in production builds contribute to bundle size and can inadvertently leak internal state in browser devtools. Removing them at compile time keeps production bundles clean without requiring manual audit of every log statement.
Configuration
const config: NextConfig = {
compiler: {
removeConsole: {
exclude: ['error'],
},
},
};
This removes all console.* calls except console.error, which is retained for runtime error visibility.
Complete Reference Configuration
The following combines all recommended options into a single next.config.ts:
import type { NextConfig } from 'next';
import withBundleAnalyzer from '@next/bundle-analyzer';
const config: NextConfig = {
experimental: {
optimizePackageImports: [
'lucide-react',
'date-fns',
'@dnd-kit/core',
'@dnd-kit/sortable',
'@dnd-kit/utilities',
],
},
images: {
formats: ['image/avif', 'image/webp'],
},
compiler: {
removeConsole: {
exclude: ['error'],
},
},
};
export default withBundleAnalyzer({
enabled: process.env.ANALYZE === 'true',
})(config);
Summary of Improvements
| Area | Option | Benefit |
|---|---|---|
| Tree-shaking | experimental.optimizePackageImports | −100–200 KB (lucide-react alone) |
| Observability | @next/bundle-analyzer | Catch size regressions in CI |
| Images | images.formats | Smaller payloads for modern browsers |
| Production hygiene | compiler.removeConsole | Cleaner builds, no log leakage |
Introduced in v1.0.24. No breaking changes — all options are additive.