
- Next.js - Home
- Next.js - Overview
- Next.js - Project Setup
- Next.js - Folder Structure
- Next.js - App Router
- Next.js - Page Router
- Next.js Features
- Next.js - Pages
- Next.js - Data Fetching
- Next.js - ISR
- Next.js - Static File Serving
- Next.js - Pre-Rendering
- Next.js - Partial Pre Rendering
- Next.js - Server Side Rendering
- Next.js - Client Side Rendering
- Next.js Routing
- Next.js - Routing
- Next.js - Nested Routing
- Next.js - Dynamic Routing
- Next.js - Parallel Routing
- Next.js - Imperative Routing
- Next.js - Shallow Routing
- Next.js - Intercepting Routes
- Next.js - Redirecting Routes
- Next.js - Navigation and Linking
- Next.js Configuration
- Next.js - TypeScript
- Next.js - Environment Variables
- Next.js - File Conventions
- Next.js - ESLint
- Next.js API & Backend
- Next.js - API Routes
- Next.js - Dynamic API Routes
- Next.js - Route Handlers
- Next.js - API MiddleWares
- Next.js - Response Helpers
- Next.js API Reference
- Next.js - CLI Commands
- Next.js - Functions
- Next.js - Directives
- Next.js - Components
- Next.js - Image Component
- Next.js - Font Component
- Next.js - Head Component
- Next.js - Form Component
- Next.js - Link Component
- Next.js - Script Component
- Next.js Styling & SEO
- Next.js - CSS Support
- Next.js - Global CSS Support
- Next.js - Meta Data
- Next.js Advanced Topics
- Next.js - Error Handling
- Next.js - Server Actions
- Next.js - Fast Refresh
- Next.js - Internationalization
- Next.js - Authentication
- Next.js - Session Management
- Next.js - Authorization
- Next.js - Caching
- Next.js - Data Caching
- Next.js - Router Caching
- Next.js - Full Route Caching
- Next.js - Request Memoization
- Next.js Performance Optimization
- Next.js - Optimizations
- Next.js - Image Optimization
- Next.js - Lazy Loading
- Next.js - Font Optimization
- Next.js - Video Optimization
- Next.js - Script Optimization
- Next.js - Memory Optimization
- Next.js - Using OpenTelemetry
- Next.js - Package Bundling Optimization
- Next.js Testing
- Next.js - Testing
- Next.js - Testing with Jest
- Next.js - Testing with Cypress
- Next.js - Testing with Vitest
- Next.js - Testing with Playwright
- Next.js Debugging & Deployment
- Next.js - Debugging
- Next.js - Deployment
- Next.js Useful Resources
- Next.js - Interview Questions
- Next.js - Quick Guide
- Next.js - Useful Resources
- Next.js - Discussion
Next.js - Optimize Package Bundlings
In this chapter, we will learn what is package bundling, how to analyze and optimize package bundling in Next.js, and how to use different techniques to optimize package bundling.
What is Package Bundling?
Package bundling is the process of combining multiple JavaScript files and their dependencies into a single file. Next.js automatically analyses the application dependency graph and split code into manageable chunks, and then create separate bundles for client-side and server-side code. In general, Next.js will split your code it to,
- Client-side bundles for browser execution
- Server-side bundles for SSR/SSG
- Route-based chunks for automatic code splitting
- Shared chunks for commonly used code
Analyzing Package Bundles in Next.js
Before optimizing the package bundling, it is important to understand how Next.js handles package bundling. Next.js provides a built-in tool to analyze the package bundling of your application. It generates a visual report of the size of each package and their dependencies. You can use the information to remove large dependencies, split, or lazy-load your code.
Install and Setup Analysis Tools
To analyze the package bundling, you need to install the analysis tools. Run the following command in your terminal.
npm i @next/bundle-analyzer
After installing the analysis tools, edit the next.config.js file and add the following code:
// File - /next.config.js /** @type {import('next').NextConfig} */ const nextConfig = {} const withBundleAnalyzer = require('@next/bundle-analyzer')({ enabled: process.env.ANALYZE === 'true', }) module.exports = withBundleAnalyzer(nextConfig)
Generate HTML report
After setting up the analysis tools, you can generate an HTML report by running the following command:
$env:ANALYZE="true"; npm run build
Output
Next.js will generate a detailed HTML report of the package bundling. The report shows the size of each package and their dependencies. See the image below for an example.

Optimizing Package Bundles
The section below explain different methods to optimize package bundling in Next.js applications.
Removing Unwanted Packages
Sometimes, you may not need all the packages in a module for your application. You can remove unwanted packages out of bundling using the 'serverExternalPackages' option in your next.config.js. The following code shows how to remove the 'react' package from bundling.
// File - /next.config.js /** @type {import('next').NextConfig} */ const nextConfig = { serverExternalPackages: ['react'], } module.exports = nextConfig
Using Dynamic Imports
To further optimize package bundling, you can use dynamic imports to load components on-demand. This can significantly reduce the initial bundle size and improve the performance of your application. Here's an example of how to use dynamic imports:
const DynamicComponent = dynamic( () => import('./components/HeavyComponent'), { loading: () =>Loading component...
} );
Configuring Optimized Package Imports
Sometimes certain packages, such as icon libraries, may contain hundreds of modules for exporting, which can cause performance issues in development and production. We can optimize the importing of these packages by adding the 'optimizePackageImports' option to our 'next.config.js' file. By this setting this option, Next.js will only load the modules we actually use, while still giving you the convenience of writing import statements with many named exports.
/** @type {import('next').NextConfig} */ const nextConfig = { experimental: { optimizePackageImports: ['icon-library'], }, } module.exports = nextConfig
Tree Shaking Enhancement
Tree shaking is automatic optimization technique used by Next.js to eliminate unused dead code from application. It is a powerful way to enhance performance of application. To properly leverage tree shaking, follow the below measures.
-
Use ES Modules (ESM): ESM is a new standard for JavaScript modules that provides better tree shaking capabilities. Next.js prefers ES modules for enhanced tree shaking.
// Good: ESM import { specificFunction } from 'library'; specificFunction(); // Avoid: CommonJS const library = require('library'); library.specificFunction();
-
Optimize Third-Party Libraries: Sometimes, Next.js cannot treeshake all the third-party libraries. So you have to avoid importing entire libraries when you only need specific parts.
// Good: Import specific functions import { debounce } from 'lodash-es'; // Avoid: Importing the entire library import _ from 'lodash';