Build Tool CSS Minification Compared: Vite, Webpack, Rollup, esbuild

May 28, 20267 min read

Why CSS Minification Matters

CSS minification removes whitespace, comments, and redundant values from stylesheets. On a typical project, minification reduces CSS size by 20–30% — a meaningful improvement for page load performance.

Most modern build tools handle CSS minification automatically in production mode, but the defaults vary in aggressiveness, configurability, and output quality. Understanding these differences helps you choose the right setup for your project.

What CSS Minifiers Do

OptimizationExample BeforeExample AfterTypical Savings
Remove whitespacemargin: 10px ;margin:10pxHigh
Remove comments/* header */ .nav {}.nav{}Moderate
Merge longhand → shorthandmargin-top:10px;margin-right:10pxmargin:10pxModerate
Remove redundant valuesmargin:10px 10px 10px 10pxmargin:10pxLow
Optimize color valuescolor:#ff0000color:redLow
Remove empty rules.empty {}(removed)Low
Deduplicate selectorsTwo .btn{color:red}One .btn{color:red}Varies

Tool-by-Tool Comparison

Vite

Vite uses PostCSS with cssnano by default in production builds. Configuration lives in vite.config.ts:

// vite.config.ts
export default defineConfig({
  build: {
    cssMinify: true,  // Default in production
  },
})

For more control, replace the default with lightningcss:

export default defineConfig({
  css: {
    transformer: 'lightningcss',
  },
  build: {
    cssMinify: 'lightningcss',
  },
})

Pros: Excellent defaults, fast builds via esbuild in dev, lightningcss option is significantly faster than cssnanoCons: Limited fine-grained control over which cssnano optimizations run (without ejecting to custom PostCSS config)

Webpack

Webpack delegates CSS minification to the MiniCssExtractPlugin combined with css-minimizer-webpack-plugin:

// webpack.config.js
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin')

module.exports = {
  module: {
    rules: [
      { test: /\.css$/, use: [MiniCssExtractPlugin.loader, 'css-loader'] },
    ],
  },
  optimization: {
    minimizer: [
      new CssMinimizerPlugin({
        minimizerOptions: {
          preset: ['advanced', { discardUnused: false }],
        },
      }),
    ],
  },
  plugins: [new MiniCssExtractPlugin()],
}

Pros: Full control over cssnano preset, mature ecosystem, widely documented Cons: Slow builds on large projects, verbose configuration

Rollup

Rollup requires rollup-plugin-postcss for CSS handling:

import postcss from 'rollup-plugin-postcss'

export default {
  plugins: [
    postcss({
      minimize: true,
      extract: 'styles.css',
    }),
  ],
}

By default it uses cssnano. You can pass custom PostCSS plugins for different minifiers.

Pros: Simple API when you just need basic CSS extraction and minification Cons: Less ecosystem support than Webpack for CSS-specific features like code splitting

esbuild

esbuild can bundle CSS but has limited minification capabilities:

esbuild app.css --bundle --minify --outfile=dist/app.css

esbuild's CSS minification is fast but basic — it removes whitespace and comments but doesn't perform advanced optimizations like merging longhand properties or converting colors.

Pros: Extremely fast — processes large CSS files近乎瞬间 Cons: No advanced optimizations, no PostCSS plugin support for CSS minification

Output Size Comparison

These results come from minifying a 150 KB CSS file (Tailwind output + custom styles):

ToolOutput SizeMinification RatioBuild Time
Unminified150 KB
esbuild112 KB25%15ms
cssnano (default)105 KB30%850ms
cssnano (advanced)100 KB33%1200ms
lightningcss102 KB32%45ms

Takeaway: lightningcss achieves near-cssnano quality at 20× the speed. For most projects, the 2–3 KB difference between lightningcss and cssnano isn't worth the build time penalty.

Choosing Based on Project Needs

ScenarioRecommended SetupWhy
New project, any frameworkVite + lightningcssBest speed-to-quality ratio
Existing Webpack projectcss-minimizer-webpack-plugin + cssnanoNo migration needed
Library build (small CSS)Rollup + cssnanoClean output, tree-shaking
Ultra-fast CI buildsesbuild CSS minifySpeed matters more than 5% size difference
Maximum compressioncssnano advanced presetEvery byte counts (mobile, embedded)

Advanced: Custom cssnano Configuration

If you need specific optimizations enabled or disabled:

// postcss.config.js
module.exports = {
  plugins: [
    require('cssnano')({
      preset: [
        'advanced',
        {
          discardComments: { removeAll: true },
          mergeLonghand: true,
          cssDeclarationSorter: false,  // Disable if order matters for specificity
          reduceIdents: false,          // Disable to preserve animation names
        },
      ],
    }),
  ],
}

Common options to toggle:

  • reduceIdents: Renames @keyframes and @counter-style identifiers — disable if you reference them from JavaScript
  • cssDeclarationSorter: Reorders declarations — disable if property order affects your overrides
  • autoprefixer: Add vendor prefixes during minification rather than as a separate step

Key Takeaways

  • CSS minification typically reduces file size by 20–30%
  • Vite + lightningcss offers the best speed-to-quality ratio for most projects
  • cssnano with advanced preset achieves maximum compression but is significantly slower
  • esbuild minifies CSS instantly but skips advanced optimizations like shorthand merging
  • Webpack requires explicit css-minimizer-webpack-plugin configuration
  • Be cautious with reduceIdents and cssDeclarationSorter — they can break JavaScript-referenced animation names and specificity-dependent overrides

Try It Yourself

Minify your CSS instantly with our free CSS Minifier. Paste your stylesheet and get optimized output in one click — no build setup required.