Performance

How to Use Code Splitting to Reduce Initial Load Times in Next.js

Blazity team
9 May 2025
2 min. read

What Is Code Splitting?

Code splitting is a technique for optimizing web applications by breaking down the codebase into smaller, manageable chunks loaded separately. In Next.js, code splitting works closely with dynamic imports.

How do Next.js dynamic imports differ from static imports?

Dynamic imports use code splitting to break up the application into smaller, on-demand chunks loaded only when needed, improving page load times by initially sending less code.

Strategies for segmenting code:

  • Pages: Separate bundles for different routes (Next.js default)
  • Components: Individual or groups of components as separate chunks
  • Libraries: Distinct chunks for third-party libraries
  • Features: Code related to specific features
  • User Interactions: Modules loaded based on specific user actions

Ignoring Code Splitting Risks:

  • Slower Load Times & Poor UX: Users must download the entire app upfront
  • Higher Bounce Rates & SEO Impact: Poor performance metrics hurt search rankings
  • Security Risks: Including sensitive content in the main bundle

How to Implement Code Splitting?

next/dynamic (Pages Router)

import dynamic from 'next/dynamic';
import { useState } from 'react';
 
const Modal = dynamic(() => import('../components/Modal'));
 
export const GenericComponent = () => {
  const [isModalOpen, setIsModalOpen] = useState(false);
 
  return (
    <div>
      <h1>Welcome to My Next.js App</h1>
      <button onClick={() => setIsModalOpen(true)}>Open Modal</button>
      {isModalOpen && <Modal onClose={() => setIsModalOpen(false)} />}
    </div>
  );
};

Good candidates for dynamic imports:

  • Heavy Components (charts, maps, editors)
  • Rarely Used Components (modals, dialogs, tooltips)
  • Device-Specific Components
  • Auth-Based Components
  • Locale-Specific UI

Disabling SSR

export const HeavyComponent = dynamic(() => import('../components/header'), {
  ssr: false,
  loading: () => <div>Loading…</div>
});

next/dynamic (App Router)

Next.js 13+ supports React Server Components, which are automatically code-split by default. Dynamic imports are still relevant for client components:

'use client'
import dynamic from 'next/dynamic'
 
const TrueClientComponent = dynamic(() => import('../components/TrueClientComponent'), { ssr: false })

Automatic Code Splitting

Each page is loaded as a separate chunk with benefits:

  • Isolated Error Handling: Errors on one page don't affect others
  • Optimized Bundle Size: Users load only code needed for visited pages
  • Prefetching: Next.js preloads linked pages in the background

External Modules

Dynamically import heavy libraries only when needed:

import { useState, useRef } from 'react'
 
export const PdfComponent = () => {
  const pdfLibRef = useRef(null)
 
  const handleInputFocus = async () => {
    if (!pdfLibRef.current) {
      const jsPdfModule = await import('jspdf')
      pdfLibRef.current = jsPdfModule.default
    }
  }
 
  // ...
}

Key Points

  1. Use dynamic imports and next/dynamic to load code only when needed.
  2. Next.js automatically splits pages into separate chunks.
  3. Disabling SSR ensures that a component loads only on the client.
  4. Large conditional UI elements benefit from dynamic imports.
  5. Server components are automatically code-split.
  6. Code splitting separates pages and components into small chunks, reducing bundle size.

Subscribe to our newsletter

Get Next.js tips, case studies, and frontend insights delivered to your inbox.

By clicking Sign Up you request to receive newsletters from us in accordance with Website Terms. The Controller of your personal data is Blazity Sp. z o.o. with its registered office at Warsaw, Poland, who processes your personal data for marketing purposes. You have the right to data access, rectification, erasure, restriction and portability, object to processing and to lodge a complaint with a supervisory authority. For detailed information, please refer to the Privacy Policy.
Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.