Code and Bundle

Back

Loading concept...

📦 Next.js Code & Bundle Optimization

The Backpack Story 🎒

Imagine you’re going on a trip. You have a huge backpack filled with everything you own—books, toys, clothes, snacks, even a sleeping bag!

But wait… do you really need ALL of that for a quick trip to the park?

Nope! You only need a water bottle and maybe a ball.

Your Next.js app is just like that backpack. When you build it, you might pack way too much code—stuff users don’t even need right away. This makes your app slow and heavy.

Today, we’ll learn how to pack smart—only what you need, when you need it!


🎯 What We’ll Learn

  1. next/dynamic – Load parts of your app only when needed
  2. ssr Option – Choose if code runs on server or browser
  3. loading Option – Show something pretty while waiting
  4. @next/bundle-analyzer – See what’s making your backpack heavy
  5. React Compiler – Magic helper that makes code faster
  6. optimizePackageImports – Smart packing for big libraries

1️⃣ The next/dynamic Function

What Is It?

Think of next/dynamic as a magic door. Behind this door is a room with special tools (your component). But you only open the door when you actually need those tools.

Instead of carrying everything in your backpack from the start, you leave some things in a locker and grab them later!

Simple Example

import dynamic from 'next/dynamic'

// This component loads ONLY when needed
const HeavyChart = dynamic(
  () => import('./HeavyChart')
)

export default function Dashboard() {
  return (
    <div>
      <h1>My Dashboard</h1>
      <HeavyChart />
    </div>
  )
}

What Happens?

  1. User visits your page
  2. Page loads fast (no heavy chart yet!)
  3. When HeavyChart is needed, it loads
  4. User sees the chart

Result: Faster first load! ⚡


2️⃣ The ssr Option

What Is SSR?

SSR = Server-Side Rendering

Imagine a restaurant:

  • SSR ON: Chef cooks your food in the kitchen, brings it ready
  • SSR OFF: Chef gives you ingredients, you cook at your table

Some components only work “at the table” (in the browser). They need things like window or document that don’t exist in the kitchen (server).

When to Turn SSR Off

import dynamic from 'next/dynamic'

// This chart uses browser-only features
const BrowserOnlyChart = dynamic(
  () => import('./BrowserOnlyChart'),
  { ssr: false }  // 👈 Don't run on server!
)

Real Example

// ❌ This breaks on server
// (window doesn't exist there!)
const MapComponent = dynamic(
  () => import('./MapWithLeaflet'),
  { ssr: false }
)

Quick Guide

Situation Use ssr: false?
Uses window or document ✅ Yes
Uses browser-only library ✅ Yes
Works everywhere ❌ No (keep SSR)

3️⃣ The loading Option

The Waiting Game

When you order pizza, what do you do while waiting? You don’t just stare at an empty table! Maybe you set up plates, pour drinks, or watch TV.

The loading option is like that—it shows something nice while your component loads.

How to Use It

import dynamic from 'next/dynamic'

const SlowComponent = dynamic(
  () => import('./SlowComponent'),
  {
    loading: () => (
      <div className="spinner">
        Loading magic... ✨
      </div>
    )
  }
)

Better Example with Skeleton

const ProductList = dynamic(
  () => import('./ProductList'),
  {
    loading: () => (
      <div className="skeleton">
        <div className="skeleton-item" />
        <div className="skeleton-item" />
        <div className="skeleton-item" />
      </div>
    )
  }
)

Why This Matters

Without loading With loading
Empty space 😕 Nice placeholder 😊
User confused User knows to wait
Feels broken Feels professional

4️⃣ @next/bundle-analyzer

X-Ray Vision for Your Backpack 🔍

Remember our backpack? What if you could see exactly what’s inside and how heavy each item is?

@next/bundle-analyzer is like X-ray vision! It shows you:

  • What’s in your bundle
  • How big each piece is
  • What’s making your app slow

Setup Steps

Step 1: Install it

npm install @next/bundle-analyzer

Step 2: Configure it

// next.config.js
const withBundleAnalyzer = require(
  '@next/bundle-analyzer'
)({
  enabled: process.env.ANALYZE === 'true',
})

module.exports = withBundleAnalyzer({
  // your config here
})

Step 3: Run it

ANALYZE=true npm run build

What You’ll See

graph TD A["Your App Bundle"] --> B["react: 40KB"] A --> C["lodash: 70KB 😱"] A --> D["your-code: 20KB"] A --> E["moment: 60KB 😱"] style C fill:#ff6b6b style E fill:#ff6b6b

Red = Too big! Time to optimize!

Pro Tips

  • Look for big red boxes (heavy packages)
  • Ask: “Do I need ALL of this library?”
  • Consider smaller alternatives

5️⃣ React Compiler

Your Personal Code Helper 🤖

Imagine you have a helpful robot friend. Every time you write code, the robot looks at it and says:

“Hey! I can make this faster for you!”

That’s the React Compiler! It automatically optimizes your React code.

What It Does

Before (your code):

function ProductCard({ product }) {
  // This runs every render 😓
  const price = formatPrice(product.price)

  return <div>{price}</div>
}

After (compiler optimizes):

// Compiler adds useMemo automatically!
// Now it only runs when needed 🎉

How to Enable It

// next.config.js
module.exports = {
  experimental: {
    reactCompiler: true,
  },
}

What It Optimizes

Problem Compiler Fix
Re-renders too much Adds memoization
Functions recreated Stabilizes them
Objects recreated Caches them

Important Notes

  • 🧪 Still experimental (but getting stable!)
  • ✅ Works with existing React code
  • 🚀 No code changes needed from you

6️⃣ optimizePackageImports Config

The Smart Shopping List 🛒

Imagine going to a huge supermarket for just milk. Instead of walking through every aisle, what if someone handed you just the milk at the door?

That’s optimizePackageImports! When you import from big libraries, Next.js grabs only what you need.

The Problem

// ❌ Bad: Loads ENTIRE library
import { Button } from 'huge-ui-library'
// Even though you only need Button,
// you might get 100 other components!

The Solution

// next.config.js
module.exports = {
  experimental: {
    optimizePackageImports: [
      'huge-ui-library',
      '@mui/material',
      'lodash',
      'date-fns',
    ],
  },
}

Now when you write:

import { Button } from 'huge-ui-library'

Next.js automatically converts it to:

// ✅ Only loads the Button!
import Button from 'huge-ui-library/Button'

Built-in Optimizations

Next.js already optimizes these popular libraries:

  • lucide-react
  • date-fns
  • lodash-es
  • @mui/icons-material
  • @heroicons/react
  • And many more!

Before vs After

graph LR A["Your Import"] --> B{optimizePackageImports} B --> C["Only What You Need"] B --> D["Smaller Bundle"] B --> E["Faster Load"] style C fill:#4ade80 style D fill:#4ade80 style E fill:#4ade80

🎒 Putting It All Together

Let’s use everything we learned in one example:

// next.config.js
const withBundleAnalyzer = require(
  '@next/bundle-analyzer'
)({
  enabled: process.env.ANALYZE === 'true',
})

module.exports = withBundleAnalyzer({
  experimental: {
    reactCompiler: true,
    optimizePackageImports: [
      '@mui/material',
      'lodash',
    ],
  },
})
// components/Dashboard.jsx
import dynamic from 'next/dynamic'

// Heavy chart - load dynamically
const AnalyticsChart = dynamic(
  () => import('./AnalyticsChart'),
  {
    loading: () => <ChartSkeleton />,
    ssr: false  // Uses browser APIs
  }
)

// Map component - browser only
const InteractiveMap = dynamic(
  () => import('./InteractiveMap'),
  {
    loading: () => <MapPlaceholder />,
    ssr: false
  }
)

export default function Dashboard() {
  return (
    <div>
      <h1>Smart Dashboard</h1>
      <AnalyticsChart />
      <InteractiveMap />
    </div>
  )
}

🌟 Quick Summary

Tool What It Does When to Use
next/dynamic Lazy load components Heavy components
ssr: false Skip server rendering Browser-only code
loading Show placeholder Better UX
bundle-analyzer See bundle size Finding problems
reactCompiler Auto-optimize Always (if stable)
optimizePackageImports Tree-shake imports Big libraries

🎯 Remember This!

“Pack light, travel fast!” 🚀

Your Next.js app should only carry what it needs, when it needs it. Use these tools to:

  1. ✅ Load heavy stuff later (dynamic)
  2. ✅ Skip server when needed (ssr: false)
  3. ✅ Show nice loading states (loading)
  4. ✅ See what’s heavy (bundle-analyzer)
  5. ✅ Let compiler help (reactCompiler)
  6. ✅ Import only what you use (optimizePackageImports)

Now go make your apps lightning fast! ⚡

Loading story...

Story - Premium Content

Please sign in to view this story and start learning.

Upgrade to Premium to unlock full access to all stories.

Stay Tuned!

Story is coming soon.

Story Preview

Story - Premium Content

Please sign in to view this concept and start learning.

Upgrade to Premium to unlock full access to all content.