Performance
Bundle Optimization
Learn how to analyze and reduce Next.js bundles with Server Components, dynamic imports, package import optimization, and analyzer tools.
## 1. Learning Objectives
By the end of this lesson, you will be able to identify large client bundles, move static heavy work to Server Components, lazy-load expensive widgets, and use analyzer tools to guide optimization.
Difficulty: Intermediate.
## 2. Prerequisites
- Client and Server Components.
- Lazy loading.
- Build basics.
## 3. Overview
Bundle optimization reduces the JavaScript and CSS users must download, parse, and execute. Next.js already performs code splitting and tree shaking, but apps still need careful client boundaries and dependency choices.
## 4. Why This Topic Matters
Large bundles slow startup, hurt Core Web Vitals, and increase cost for users on slower devices. Many performance wins come from shipping less JavaScript.
## 5. Real-World Analogy
Bundle optimization is like packing for a trip. Bring what you need for the first day in your carry-on, and avoid dragging the entire garage through the airport.
## 6. Core Concepts
| Concept | Meaning |
|---|---|
| Bundle | Built output chunk sent to client or server. |
| Tree shaking | Removing unused exports. |
| Code splitting | Loading separate chunks by route or demand. |
| Analyzer | Tool that shows bundle composition. |
| Client boundary | `"use client"` line that controls browser bundle reach. |
## 7. Syntax & API Reference
## 8. Visual Diagram
## 9. Live Example - Full Working Code
What just happened? Removing the client boundary keeps the heavy markdown library out of the browser bundle when no browser interactivity is required.
## 10. Interactive Playground
Try this:
- Search for broad `"use client"` files.
- Move non-interactive rendering to Server Components.
- Lazy-load a large editor or chart.
## 11. Common Mistakes
| Mistake | Why It Happens | Correct Approach |
|---|---|---|
| Huge client boundaries | Hooks are used high in the tree. | Push client boundaries down. |
| Importing entire icon libraries | Named imports look tree-shakeable. | Use supported package optimization or direct imports. |
| Optimizing without measurement | Guessing feels faster. | Use analyzer/build output to confirm. |
## 12. Best Practices
- Keep Client Components small.
- Move static heavy work to Server Components.
- Lazy-load non-critical widgets.
- Avoid large dependencies for small tasks.
- Use analyzer tools before and after changes.
## 13. Browser Compatibility
| Feature | Browser Impact | Notes |
|---|---|---|
| Smaller JS | Faster parse/execute | Helps all browsers. |
| Dynamic import | Modern support via bundler | Enables on-demand chunks. |
| Server Components | Less client JS | Framework-managed. |
## 14. Interview Questions
**Easy:** What is a bundle?
Answer: Built JavaScript/CSS output sent to the client or used by the server.
**Medium:** Why do broad Client Components increase bundle size?
Answer: Imports below a client boundary can be included in browser JavaScript.
**Hard:** How do you optimize a static syntax highlighter?
Answer: Run highlighting in a Server Component so the highlighter library is not shipped to the client.
## 15. Debugging Exercise
Bug report: "The homepage ships a large charting library even though charts are below a tab."
Solution
Move the chart into a lazy Client Component loaded only when the tab opens, or render static chart output on the server if interaction is not needed.
## 16. Practice Exercises
- Easy: Identify all `"use client"` files in a feature.
- Medium: Lazy-load a heavy editor.
- Hard: Replace a client-side static formatter with a Server Component.
## 17. Scenario-Based Challenge
An app imports a markdown renderer, chart library, and icon library in the root dashboard client component. What should change first?
Walkthrough
Split the dashboard into smaller client islands, move markdown rendering server-side, lazy-load charts, and optimize icon imports.
## 18. Quick Quiz
1. What directive expands client bundle boundaries? Answer: `"use client"`.
2. What delays heavy widgets? Answer: Dynamic import/lazy loading.
3. What removes unused code? Answer: Tree shaking.
4. What helps inspect bundle contents? Answer: Bundle analyzer.
5. Should static heavy work run client-side? Answer: Usually no.
## 19. Summary & Key Takeaways
- Ship less JavaScript whenever possible.
- Server Components reduce client bundle size.
- Lazy loading defers non-critical code.
- Analyze before optimizing.
- Dependency choices matter.
## 20. Cheat Sheet
| Problem | Fix |
|---|---|
| Heavy client formatter | Move to server |
| Hidden chart in initial JS | Lazy-load |
| Huge icon package | Optimize imports |
| Broad client page | Split into islands |
| Unknown bundle source | Run analyzer |
## 21. Further Reading
- Next.js Docs: Package Bundling.
- Next.js Docs: Lazy Loading.
- web.dev: JavaScript performance.
## 22. Next Lesson Preview
Chapter 7 is complete. Next, you will move into deployment topics.