Minify CSS and JavaScript: Remove Unnecessary Bytes
Unminified CSS and JavaScript files contain whitespace, comments, and long variable names that add kilobytes to every download. Learn how to minify them.
Shipping unminified code to production is like mailing a letter with all your drafts and notes attached. Strip the unnecessary bytes and ship only what the browser needs.
Why Minification Matters
| Before Minification | After | Savings | |
|---|---|---|---|
| Typical JS file | 200KB | 130KB | 35% |
| Typical CSS file | 80KB | 55KB | 31% |
| + Brotli compression | 55KB | 40KB | +27% |
Combined with compression, you're serving 50-60% less data.
What Minification Removes
JavaScript
// Before (readable)
function calculateTotal(items) {
// Loop through all items and sum their prices
let total = 0;
for (const item of items) {
total += item.price * item.quantity;
}
return total;
}
// After minification
function calculateTotal(t){let e=0;for(const n of t)e+=n.price*n.quantity;return e}
CSS
/* Before (readable) */
.hero-section {
display: flex;
align-items: center;
justify-content: center;
min-height: 100vh;
/* Full viewport height */
background-color: #1a1a2e;
}
/* After minification */
.hero-section{display:flex;align-items:center;justify-content:center;min-height:100vh;background-color:#1a1a2e}
How to Minify
Next.js (Automatic)
Next.js minifies CSS and JavaScript automatically in production:
# Production build — minified automatically
next build
# Development — NOT minified (this is expected)
next dev
If Lighthouse flags unminified code in a Next.js app, check that:
- You're testing the production build, not
next dev - Third-party scripts in
public/aren't unminified
Vite (Automatic)
Vite uses esbuild for JS and Lightning CSS for CSS:
# Automatically minified
vite build
Webpack
const TerserPlugin = require("terser-webpack-plugin");
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
module.exports = {
mode: "production", // Enables minification
optimization: {
minimizer: [
new TerserPlugin({
terserOptions: {
compress: { drop_console: true }, // Remove console.log
},
}),
new CssMinimizerPlugin(),
],
},
};
PostCSS + cssnano
// postcss.config.js
module.exports = {
plugins: [
require("autoprefixer"),
require("cssnano")({
preset: ["default", {
discardComments: { removeAll: true },
}],
}),
],
};
CLI Tools
# JavaScript — Terser
npx terser input.js -o output.min.js --compress --mangle
# CSS — cssnano via PostCSS CLI
npx postcss input.css -o output.min.css --use cssnano
# HTML — html-minifier
npx html-minifier --collapse-whitespace --remove-comments \
input.html -o output.min.html
Tailwind CSS Purging
Tailwind generates thousands of utility classes. Purge unused ones:
// tailwind.config.js — v3+ does this automatically in production
module.exports = {
content: [
"./src/**/*.{js,ts,jsx,tsx}",
"./app/**/*.{js,ts,jsx,tsx}",
],
};
Before purging: 3.5MB CSS After purging: 8-15KB CSS
Common Issues
Serving Development Builds
The most common cause of unminified code in production:
# ❌ Serves unminified code
NODE_ENV=development next start
# ✅ Build for production, then serve
NODE_ENV=production next build
next start
Unminified Third-Party Scripts
Scripts in public/ or loaded from CDNs may not be minified:
<!-- Check if there's a .min.js version -->
<script src="/js/legacy-plugin.js"></script>
<!-- ✅ Use the minified version -->
<script src="/js/legacy-plugin.min.js"></script>
Inline Scripts and Styles
Inline code in your HTML isn't minified by bundlers:
<!-- ❌ Unminified inline script -->
<script>
// This won't be minified by Webpack/Vite
const greeting = "hello";
console.log(greeting);
</script>
<!-- ✅ Move to a bundled file or minify manually -->
<script src="/js/init.js"></script>
Quick Wins Checklist
- Verify you're serving production builds (
NODE_ENV=production) - Check that your build tool minifies CSS and JS (it probably does)
- Purge unused Tailwind CSS classes (automatic in v3+)
- Minify any custom scripts in
public/folder - Remove
console.logstatements in production builds - Enable CSS and JS source maps only in development
Ready to stop wasting ad spend?
Track your landing page performance, monitor Core Web Vitals, and calculate exactly how much slow pages cost you.
Start Free — No Credit Card