Prompt of the Day: Optimize Your Bundle Size with Code Splitting
Part 28 of 30 -- Prompt of the Day
Every kilobyte your app ships on the initial load is a tax on your users. A bloated JavaScript bundle means slower Time to Interactive, higher bounce rates, and a worse experience on mobile networks. Code splitting is the discipline of breaking that monolithic bundle into smaller, demand-loaded chunks so users only download the code they actually need for the current page.
The Prompt
You are a senior performance engineer auditing a React / Next.js application for bundle bloat.
Step 1 -- Analyze the bundle:
- Run `ANALYZE=true npm run build` using @next/bundle-analyzer and identify the five largest chunks by parsed size.
- List each chunk name, its parsed size in KB, and the top three modules contributing to it.
Step 2 -- Find candidates for dynamic import:
- Identify any component or library that meets at least one of these criteria:
(a) it is only rendered below the fold or after user interaction (modals, drawers, tooltips, charts, rich text editors),
(b) it is a third-party library larger than 50 KB gzipped that is not needed on first paint,
(c) it is a route that is not the landing page or a critical conversion path.
Step 3 -- Implement lazy loading:
- For plain React projects, convert identified components to React.lazy() with a Suspense boundary and a meaningful fallback (skeleton or spinner).
- For Next.js projects, use next/dynamic with a loading prop; set ssr: false only for components that use browser-only APIs.
- Wrap all lazy boundaries in an ErrorBoundary component that renders a graceful fallback and logs the error.
Step 4 -- Fix barrel files:
- Scan all index.ts / index.js re-export files. Identify any barrel file where the consuming code imports only one or two named exports but the barrel re-exports ten or more.
- Replace wide barrel imports with direct path imports (e.g., import { Button } from '@/components/ui/Button' instead of '@/components/ui').
Step 5 -- Check for duplicate dependencies:
- Run `npx duplicate-package-checker-webpack-plugin` or inspect the bundle analyzer treemap for multiple copies of the same package (common with lodash, date-fns, and icon libraries).
- For each duplicate, trace which packages introduce the extra copy and resolve via package.json resolutions or alias configuration.
After each step, show a before/after size estimate so I can track progress.
Why It Works
This prompt does four things that generic "make it faster" prompts do not.
It gives the AI a concrete measurement first. Before changing a single line of code, step one produces real numbers. Without those numbers, an AI will guess which components are heavy. With them, it attacks the actual offenders.
It defines lazy-loading criteria precisely. "Anything heavy" is not actionable. The criteria in step two -- below-the-fold, interaction-gated, oversized third-party, non-critical route -- give the AI a decision framework it can apply consistently across your entire component tree.
It separates React.lazy from next/dynamic intentionally. These are not interchangeable. next/dynamic handles SSR hydration mismatches that React.lazy does not. The prompt encodes that distinction so the AI picks the right tool for the right context.
It targets barrel files explicitly. A 2026 real-world case study found that fixing wildcard icon imports alone removed 300 KB of uncompressed JavaScript from First Load JS -- more than most lazy-loading wins. Barrel files are the silent killers most audits skip. (Source: https://buildwithmatija.com/blog/reduce-nextjs-bundle-size-payload-cms-optimization)
The Anti-Prompt
"Make my React app load faster by adding lazy loading."
Here is exactly why this fails. It gives the AI no starting point -- no analysis, no size data, no criteria. The AI will respond by wrapping one or two arbitrary components in React.lazy, congratulate itself, and miss the 800 KB charting library sitting in your main chunk. It also ignores barrel files, duplicate packages, and the SSR implications of next/dynamic. You get motion, not progress.
Variations
Variation 1 -- React Router route-based splitting
"Using React Router v6, implement route-based code splitting so that each top-level route is a separate lazy-loaded chunk with React.lazy and Suspense. Add a route-level ErrorBoundary. Show the webpack chunk output before and after."
Variation 2 -- Next.js App Router and Server Components
"Audit my Next.js App Router project. Identify Client Components (marked 'use client') that contain no interactivity and could be converted to Server Components to remove them from the client bundle entirely. Then apply next/dynamic to the remaining heavy Client Components."
Variation 3 -- Barrel file cleanup only
"Scan every index.ts barrel file in /src/components. For each one, list all named exports and which files import from the barrel. Flag any barrel where a consumer uses fewer than 20% of the exports. Output a migration plan to replace barrel imports with direct imports, including exact import path changes."
Real-World Context
The Next.js team updated its official package bundling guide in April 2026 to document both the Turbopack bundle analyzer (with import-chain tracing) and the @next/bundle-analyzer plugin for Webpack projects. (Source: https://nextjs.org/docs/app/guides/package-bundling) Either tool will surface the same class of problem: large shared chunks that load on every route. A February 2026 production case trimmed 476 KB from First Load JS using exactly the sequence above -- analyze, dynamic import the block renderer, fix icon imports, lazy-load layout widgets. The pattern works at every scale. (Source: https://buildwithmatija.com/blog/reduce-nextjs-bundle-size-payload-cms-optimization)
Ask The Guild
After running this prompt on your project: what was the single largest module in your bundle before optimization, and what did you do with it? Drop your before/after KB numbers in the thread.