Минификация CSS и JS

Минификация — удаление из исходного кода пробелов, комментариев, переносов строк и замена длинных идентификаторов на короткие без изменения функциональности, что уменьшает размер файлов на 20-60% и ускоряет их загрузку и парсинг.

Зачем нужно

Каждый килобайт JS требует загрузки, парсинга и компиляции — это дорогие операции, особенно на мобильных устройствах. Минификация вместе со сжатием (gzip/brotli) снижает размер бандла в 3-5 раз по сравнению с исходным кодом.

Где используется

  • Production сборка любого веб-приложения (Vite, webpack, esbuild, Rollup)
  • CSS фреймворки (Tailwind — агрессивный purge + минификация)
  • Inline CSS/JS в HTML

Основной контент

Что удаляет минификатор

// Исходный код (не минифицированный):
function calculateDiscount(price, discountPercent) {
  // Применяем скидку к цене
  const discountAmount = price * (discountPercent / 100);
  return price - discountAmount;
}

// После минификации (esbuild/terser):
function c(a,b){const d=a*(b/100);return a-d}
// Или ещё агрессивнее:
const c=(a,b)=>a-a*(b/100);

Инструменты минификации

Инструмент Скорость Размер Использование
esbuild Очень быстрый Хороший Vite, бандлеры
SWC Быстрый Хороший Next.js, Parcel
Terser Медленный Отличный Webpack (prod)
LightningCSS Быстрый Отличный CSS
cssnano Медленный Отличный PostCSS

Vite production сборка

// vite.config.js
import { defineConfig } from 'vite';

export default defineConfig({
  build: {
    minify: 'esbuild',    // 'esbuild' (быстро) | 'terser' (меньше)
    cssMinify: 'lightningcss',
    terserOptions: {
      compress: {
        drop_console: true,   // Удалить console.log в prod
        drop_debugger: true,
        pure_funcs: ['console.log', 'console.info'],
      },
    },
    rollupOptions: {
      output: {
        // Разделить по чанкам для лучшего кеширования
        manualChunks: {
          vendor: ['react', 'react-dom'],
          router: ['react-router-dom'],
        },
      },
    },
  },
});

Tree Shaking — удаление неиспользуемого кода

// Наряду с минификацией, tree shaking удаляет мёртвый код

// library.js (ES modules обязательны для tree shaking)
export function usedFunction() { return 'used'; }
export function unusedFunction() { return 'never imported'; }

// app.js
import { usedFunction } from './library'; // Только usedFunction попадает в бандл
usedFunction;
// unusedFunction — удалена при сборке

// ВАЖНО: CommonJS (require) не поддерживает tree shaking!
// Всегда используйте ES modules (import/export) в библиотеках

CSS: PurgeCSS + cssnano

// postcss.config.js
const purgecss = require('@fullhuman/postcss-purgecss');
const cssnano = require('cssnano');

module.exports = {
  plugins: [
    // Tailwind или ваши классы
    require('tailwindcss'),
    // Удалить неиспользуемый CSS
    purgecss({
      content: ['./src/**/*.{html,jsx,tsx,vue}'],
      defaultExtractor: content => content.match(/[\w-/:]+(?<!:)/g) || ,
    }),
    // Минифицировать оставшийся CSS
    cssnano({ preset: 'default' }),
  ],
};

Анализ размера бандла

# webpack-bundle-analyzer
npx webpack-bundle-analyzer dist/stats.json()

# Vite bundle visualizer
npm run build -- --report

# Rollup visualizer плагин:
import { visualizer } from 'rollup-plugin-visualizer';
plugins: [visualizer({ open: true, gzipSize: true })]

Частые ошибки

  • Минификация в development — замедляет сборку и HMR без пользы
  • Отключение source maps в production — невозможно диагностировать ошибки
  • Только минификация без tree shaking — мёртвый код остаётся
  • Агрессивный mangle у сторонних библиотек — может сломать reflection-зависимый код

Связанные темы

Ресурсы