Analyzing the Bundle

If you learned Next.js 10,514 before version 16, you remember a build table with Size and First Load JS columns. Those are gone: the JS bundle size metrics were removed from next build in 16.0, leaving a map of how each route is served.

Output of 97
Route (app)
┌ ○ /
├ ○ /_not-found
├ ƒ /api/vitals
├ ○ /fast
├ ƒ /live
└ ○ /slow
○  (Static)   prerendered as static content
ƒ  (Dynamic)  server-rendered on demand

Read that table first, because rendering mode dominates TTFB. /live is ƒ because it awaits headers(); the catalog routes are ○ because nothing in them touches the request. Two more symbols appear elsewhere: ● for pages prerendered from generateStaticParams, and ◐ for a partially prerendered route whose shell ships at once while the rest streams - the normal case with Cache Components (Caching and Revalidation).

For sizes, Next.js 16.1 added an analyzer built on Turbopack 10,514 's module graph. npx next experimental-analyze opens an interactive treemap on port 4000; --output writes the report to .next/diagnostics/analyze instead, to keep for a before-and-after comparison.

The Turbopack bundle analyzer on the client modules of /slow
The Turbopack bundle analyzer on the client modules of /slow

Of 2.45 MB of uncompressed client modules on /slow, highlight.js 24,999 accounts for 685.58 KB, and 666.80 KB of that is lib/languages/: Mathematica at 69.35 KB, Maxima at 21.77 KB, and roughly 190 more grammars this page will never use. Clicking a rectangle shows the import chain, so you can see which client component dragged the module across the boundary. Treat "compressed (estimated)" as a guide only: it reported 911.85 KB for /slow, while the browser downloaded 445,435 bytes.

The older @next/bundle-analyzer plugin still works, but only under next build --webpack; that build served 444,355 bytes for /slow against Turbopack's 445,435, so the two agree on the diagnosis. When a package exports hundreds of modules - icon sets, utility bundles - list it in experimental.optimizePackageImports, so only the modules you name are pulled in.