Minification is the cheapest performance win in front-end work: no architecture change, no new dependency, just the same code with the bytes browsers don't need taken out. The catches are knowing which pass to run, what mangling really renames, and why the gzip column matters as much as the raw one.
The reference engine here is Terser (BSD-2-Clause) — the minifier webpack, Vite, and Parcel all lean on. To make the levels concrete, we ran its exact browser bundle over an 823-byte cart-totals script with comments, a constant, and three functions:
| Pass | Removes | Sample → | Saved |
|---|---|---|---|
| Strip only | Comments, indentation, newlines | 651 B | 20.9% |
| Compress | Plus dead branches, constant folding, joined declarations | 598 B | 27.3% |
| Compress + mangle | Plus 1–2 character names (TAX_RATE → t) | 390 B | 52.6% |
Every pass computed the identical cart result — $68.99 subtotal, $5.69 tax, $74.68 total — which is the standard you should hold any minifier to: same behavior, fewer bytes. Your percentages will differ with your file's comment density and name lengths. Heavily commented source shrinks more; machine-generated bundles, already terse, shrink less.
Mangling is where the big wins live and the real risks too. It shortens identifiers to one or two characters, scope-aware by default: a variable inside a function gets renamed without disturbing same-named variables elsewhere. Top-level mangling (toplevel: true) also renames globals in the file, which is safe for self-contained scripts and bundles, and wrong for scripts other code calls into by name.
The breakage cases are consistent:
Function.prototype.name — anything keying on a function's name (dependency-injection containers, some frameworks' component registration) sees t instead of cartTotal.eval and new Function with string identifiers — the string isn't renamed and now points at nothing.A persistent confusion: teams minify, see 50% off, and think that's their network saving. It isn't, because transport compression already handles repetition. The same sample gzips from 393 bytes (raw) to 277 (minified) — a 29.5% wire saving, not 52.6%. Gzip squeezes repeated strings and whitespace that stripping also removes, so the two wins overlap more than they add.
The correct order is still: minify, then serve with gzip or Brotli. Minification removes what compression can't (identifier names, structural verbosity), compression removes what minification can't (long repeated strings). Measure both columns — our Minify JS tool shows raw and gzip side by side for exactly this reason.
Use strip only when the file must stay debuggable from stack traces and you can't ship source maps — line structure survives, nothing is renamed. Use compress for libraries whose exported names must survive and for code where you want dead code gone without renaming risk. Use compress + mangle for applications and self-contained bundles, which is why bundlers default there.
For one-off snippets — analytics blocks, CMS embeds, single-page scripts — a browser-based minifier beats setting up a build chain for one file. Paste, pick a pass, check the byte and gzip columns, copy. Just keep the original somewhere: minified code is a build artifact, not a source of truth.
Minified code is not protected code. Anyone can pretty-print 390 bytes back to readable form in seconds; minification deters nobody who's actually looking. If the goal is making reverse engineering expensive, that's obfuscation — string arrays, control-flow flattening, the works — a different tool with different trade-offs (ours is the JS Obfuscator). And it's not a linter either: Terser will happily minify subtly wrong code that parses. Minify after the code is correct, never as a substitute for making it correct.
Minify everything you ship, at the strongest pass your naming dependencies allow, and serve it compressed. Verify functional equivalence the boring way — run the minified file against known outputs — and keep raw sources as the artifact of record. To see what each pass buys on your own code without a build chain, run it through the Minify JS tool; for the rest of the payload, the CSS Minifier and Minify HTML siblings cover the stylesheets and markup around it.
Terser 5.51.2 in your browser: strip, compress, or compress + mangle, with byte and gzip columns. No uploads.
Minify JS →