Сжатие: gzip и brotli через плагины

Сжатие статических ресурсов в Vite напрямую влияет на скорость загрузки приложения в браузере и общую производительность фронтенда. После сборки проекта основными узкими местами становятся размер JavaScript-бандлов, CSS-файлов и прочих ассетов, которые передаются по сети. Даже при использовании современных HTTP/2 и HTTP/3, снижение объёма передаваемых данных остаётся критически важным фактором.

Vite сам по себе не выполняет gzip или brotli-сжатие в процессе dev-сервера, так как его основная задача — обеспечить быстрый HMR и разработку без лишних трансформаций. Однако в production-сборке Vite легко расширяется через плагины Rollup, что позволяет встроить этап генерации сжатых версий файлов прямо в пайплайн билда.

После выполнения команды сборки:

vite build

Vite использует Rollup для генерации статических файлов в директории dist. На этом этапе формируются:

  • JavaScript чанки
  • CSS файлы
  • статические ресурсы (изображения, шрифты и т.д.)

Сжатие может быть добавлено как дополнительный шаг, который создаёт альтернативные версии файлов:

  • .gz для gzip
  • .br для brotli

Эти файлы не заменяют оригиналы, а существуют параллельно, позволяя серверу выбирать оптимальный вариант в зависимости от заголовка Accept-Encoding.

Gzip-сжатие через плагин

Gzip является наиболее распространённым методом сжатия HTTP-ответов. Он поддерживается всеми браузерами и серверными конфигурациями.

В экосистеме Vite чаще всего используется плагин vite-plugin-compression.

Установка

npm install vite-plugin-compression -D

Подключение в vite.config.js

import { defineConfig } from 'vite'
import compression from 'vite-plugin-compression'

export default defineConfig({
  plugins: [
    compression({
      algorithm: 'gzip',
      ext: '.gz'
    })
  ]
})

Принцип работы

При сборке плагин проходит по содержимому dist и:

  • читает каждый файл (js, css, html)
  • создаёт его gzip-сжатую копию
  • сохраняет рядом с оригиналом

Результат:

dist/
  assets/
    index.js
    index.js.gz
    style.css
    style.css.gz

Brotli-сжатие и его преимущества

Brotli обеспечивает более высокую степень сжатия по сравнению с gzip, особенно для текстовых ресурсов (JS, CSS, HTML). При этом декомпрессия остаётся достаточно быстрой для браузера.

Brotli особенно эффективен в production-средах с CDN, где уменьшение размера файла напрямую снижает latency.

Подключение brotli через тот же плагин

import { defineConfig } from 'vite'
import compression from 'vite-plugin-compression'

export default defineConfig({
  plugins: [
    compression({
      algorithm: 'brotliCompress',
      ext: '.br'
    })
  ]
})

Особенности brotli

Brotli имеет несколько уровней сжатия. Их можно настроить:

compression({
  algorithm: 'brotliCompress',
  ext: '.br',
  compressionOptions: {
    level: 11
  }
})

Уровень 11 даёт максимальную степень сжатия, но увеличивает время сборки. В реальных проектах часто используют баланс между скоростью и размером (например, уровень 6–9).

Одновременное использование gzip и brotli

В продакшене часто применяются оба формата одновременно, чтобы обеспечить совместимость и максимальную эффективность доставки.

import compression from 'vite-plugin-compression'

export default {
  plugins: [
    compression({
      algorithm: 'gzip',
      ext: '.gz'
    }),
    compression({
      algorithm: 'brotliCompress',
      ext: '.br'
    })
  ]
}

В результате сервер может отдавать:

  • .br для современных браузеров
  • .gz как fallback
  • оригинал, если сжатие не поддерживается

Условное сжатие и фильтрация файлов

Не все файлы стоит сжимать. Например, изображения (jpg, png, webp) уже являются сжатыми форматами, и повторное сжатие почти не даёт выигрыша.

Плагин позволяет задать фильтр:

compression({
  algorithm: 'gzip',
  ext: '.gz',
  filter: (file) => {
    return /\.(js|css|html|svg)$/.test(file)
  }
})

Это уменьшает лишнюю нагрузку на сборку и ускоряет build-процесс.

Минимальный размер файла для сжатия

Сжатие маленьких файлов может быть неэффективным, так как overhead иногда превышает выигрыш.

Поэтому задаётся порог:

compression({
  algorithm: 'gzip',
  threshold: 1024
})

В данном случае файлы меньше 1 KB не будут сжиматься.

Сравнение gzip и brotli в реальных условиях

Разница проявляется особенно на больших bundle-файлах:

  • gzip обычно уменьшает размер на 60–70%
  • brotli может достигать 70–80%

Для типичного vendor.js размером 500 KB:

  • gzip: ~150–200 KB
  • brotli: ~100–140 KB

При этом Brotli требует больше ресурсов на этапе build, но не влияет на runtime.

Использование с CDN и серверной конфигурацией

Сжатые файлы в Vite сами по себе не активируются — сервер должен быть настроен на их отдачу.

Пример логики на уровне сервера:

  • проверка Accept-Encoding
  • выбор .br или .gz
  • fallback на оригинальный файл

Для Nginx это выглядит как правило gzip_static или brotli_static.

Влияние на кеширование

Сжатые файлы обычно кешируются агрессивно, так как они являются производными артефактами сборки. Часто применяется стратегия:

  • хешированные имена файлов (app.8fd3a1.js)
  • долгосрочный cache-control
  • immutable caching

Это позволяет безопасно хранить .gz и .br версии без риска устаревания.

Производственные нюансы

При включении сжатия в Vite важно учитывать:

  • увеличение времени сборки
  • рост размера директории dist
  • необходимость поддержки на сервере
  • дублирование файлов (оригинал + gzip + brotli)

В крупных проектах иногда выносят генерацию brotli в отдельный CI-стейдж, чтобы не замедлять локальную сборку.

Интеграция с другими плагинами Vite

Сжатие часто используется вместе с:

  • vite-plugin-legacy (поддержка старых браузеров)
  • rollup-plugin-visualizer (анализ размера бандла)
  • vite-plugin-imagemin (оптимизация изображений)

Комбинация этих инструментов позволяет существенно уменьшить общий вес приложения ещё до этапа сетевой передачи данных.