Прямой ответ
Минификация сокращает объём кода удалением пробелов и переименованием имён, поэтому загрузка выполняется быстрее без изменения поведения.
| Приём | Что сокращается |
|---|---|
| Удаление пробелов и комментариев | Объём текста |
| Переименование локальных имён | Длина идентификаторов |
| Удаление недостижимого кода | Объём неиспользуемых ветвей |
| Удаление неиспользуемых правил | Объём стилей |
npx terser dist/app.js --compress --mangle -o dist/app.min.js
Поведение кода не изменяется, поэтому минификация применяется к производственной сборке. Об отладке — в статье про source map.
Приёмы сокращения и их границы
Приёмы сокращения применяются к частям кода, поэтому часть конструкций не сокращается без изменения поведения.
Удаление пробелов. Выполняется для всех пробельных символов, кроме требуемых синтаксисом, поэтому разбор кода не нарушается.
Переименование локальных имён. Выполняется для имён с локальной областью видимости, поэтому внешние имена не изменяются.
Имена, доступные извне. Не переименовываются, поэтому обращение по имени из другого модуля продолжает работать.
Практическое следствие: переименование имени, по которому выполняется динамическое обращение, нарушает работу, поскольку строка обращения не изменяется вместе с именем.
Отдельный аспект — комментарии с директивами. Часть комментариев содержит указания для сборщика, поэтому удаление всех комментариев приводит к потере директивы и изменению состава сборки.
Удаление неиспользуемого кода и правил
Недостижимый код и неиспользуемые правила удаляются, поэтому объём результата сокращается без изменения поведения.
Недостижимые ветви. Определяются по условию, известному на этапе сборки, поэтому ветвь исключается из результата.
Неиспользуемые правила стилей. Определяются по отсутствию соответствия разметке, поэтому правило не включается в результат.
Ограничение определения. Динамическое формирование имени не определяется на этапе сборки, поэтому соответствующий код сохраняется.
Практическое следствие: удаление правила, применяемого к элементу, создаваемому динамически, приводит к отсутствию оформления, поскольку соответствие не определяется на этапе сборки.
Влияние на кэш и проверка результата
Объём результата влияет на загрузку, а изменение состава — на действительность кэша, поэтому минификация сопровождается версионированием файлов.
Версия в имени файла. Изменение состава меняет имя, поэтому кэш не отдаёт прежнюю версию.
Сжатие при передаче. Выполняется отдельно от минификации, поэтому объём передачи сокращается дополнительно.
Проверка результата. Выполняется после минификации, поэтому нарушение поведения обнаруживается до выпуска.
Практическое следствие: минификация без изменения имени файла приводит к отдаче прежней версии из кэша, поэтому пользователь получает старый код после выпуска.
Об удалении неиспользуемого кода — в статье про tree shaking; о стратегиях кэша — в статье про кэширование браузера.
Проверка результата и воспроизводимость
Минифицированный результат проверяется, поэтому нарушение поведения обнаруживается до выпуска версии.
Проверка в производственном режиме. Выполняется для собранного результата, поэтому нарушение, возникающее только после минификации, обнаруживается.
Воспроизводимость результата. Одинаковые входные данные дают одинаковый результат, поэтому различие указывает на изменение состава.
Сопоставление с исходником. Выполняется по карте, поэтому место нарушения определяется по исходному коду.
Практическое следствие: проверка только режима разработки не обнаруживает нарушение, возникающее после минификации, поэтому ошибка проявляется у посетителя, а не до выпуска.
Практика: настройка минификации
1. Применяйте минификацию только к производственной сборке. Отладка в режиме разработки выполняется по читаемому коду.
2. Сохраняйте имена, доступные извне. Обращение по имени из другого модуля продолжает работать.
3. Сохраняйте комментарии с директивами. Состав сборки не изменяется из‑за потери указания.
4. Проверяйте динамически применяемые правила стилей. Правило не удаляется при отсутствии статического соответствия.
5. Версионируйте имя файла при изменении состава. Кэш не отдаёт прежнюю версию.
6. Включайте сжатие при передаче. Объём передачи сокращается дополнительно.
7. Проверяйте поведение после минификации. Нарушение обнаруживается до выпуска версии.
Рекомендации:
- Не переименовывайте имена, по которым выполняется динамическое обращение. Строка обращения не изменяется вместе с именем.
- Не удаляйте все комментарии без проверки директив. Часть комментариев содержит указания для сборщика.
- Не удаляйте правила, применяемые к динамически создаваемым элементам. Соответствие не определяется на этапе сборки.
- Фиксируйте проверку результата после минификации. Нарушение поведения обнаруживается до выпуска.
- Пересматриваем настройку при изменении способа обращения к коду. Динамическое обращение требует сохранения имени.
Практический сценарий: часть интерфейса потеряла оформление после выпуска
Контекст: после выпуска минифицированной сборки часть элементов отображалась без оформления, хотя в режиме разработки оформление применялось.
- Диагностика. Проверка показала, что правила стилей для этих элементов были удалены как неиспользуемые. Элементы создавались динамически, поэтому соответствие правила разметке не определялось на этапе сборки, и правило исключалось из результата.
- Причина. Удаление неиспользуемых правил выполнялось без учёта динамически создаваемых элементов, поэтому часть правил, фактически применяемых, была исключена из производственной сборки.
- Действия. (а) Отметили правила, применяемые к динамически создаваемым элементам, как используемые, чтобы они не исключались из результата; (б) настроили сохранение имён, по которым выполняется динамическое обращение, чтобы переименование не нарушало работу; (в) настроили сохранение комментариев с директивами, чтобы состав сборки не изменялся; (г) добавили проверку производственной сборки в набор проверок, чтобы нарушение обнаруживалось до выпуска; (д) настроили версионирование имени файла при изменении состава, чтобы кэш не отдавал прежнюю версию.
- Результат. Оформление применяется ко всем элементам, поскольку правила для динамически создаваемых элементов сохраняются, а проверка выполняется для производственной сборки.
Вывод: удаление неиспользуемых правил не определяет соответствие для динамически создаваемых элементов, поэтому часть фактически применяемых правил исключается. Отметка таких правил как используемых, сохранение имён при динамическом обращении и проверка производственной сборки обеспечивают соответствие результата ожиданию.
FAQ
Что делает минификация? Удаляет пробелы и комментарии, переименовывает локальные имена и исключает недостижимый код. Поведение не изменяется.
Какие имена не переименовываются? Доступные извне и используемые при динамическом обращении. Строка обращения не изменяется вместе с именем.
Почему может пропасть оформление после минификации? Правило удалено как неиспользуемое, хотя применяется к динамически создаваемому элементу. Соответствие не определяется на этапе сборки.
Нужно ли версионировать имя файла после минификации? Да. Без изменения имени кэш отдаёт прежнюю версию, поэтому пользователь получает старый код.
Источники: Terser Webpack Plugin, cssnano, RFC 9110 HTTP Semantics — ссылки в шапке.