Tree shaking — это метод оптимизации, применяемый в сборщиках JavaScript, таких как Webpack, Rollup и Parcel, который позволяет удалять неиспользуемый код из финального бандла. Этот процесс снижает размер файлов, улучшает производительность загрузки и повышает эффективность выполнения кода в браузере. Основная идея заключается в статическом анализе зависимостей модулей и исключении экспортов, которые не используются в приложении.
ES6-модули как основа Tree shaking работает
только с синтаксисом ES6 import и export. Это
связано с тем, что компилятор может точно определить, какие экспорты
используются и какие нет. CommonJS
(require/module.exports) не позволяет
проводить такой анализ на этапе сборки, так как динамическое присвоение
делает статический анализ невозможным.
Статический анализ кода Сборщик сканирует все модули, строит граф зависимостей и отмечает используемые экспорты. Экспорт, который нигде не используется, помечается как “мертвый код” (dead code) и исключается из финального бандла.
Минификация и удаление мертвого кода После анализа мертвый код может быть удален на этапе минификации. Популярные инструменты, такие как Terser, умеют распознавать неиспользуемые функции и переменные, полностью исключая их из финального файла.
Webpack Чтобы Webpack корректно применял tree shaking, необходимо:
mode: "production" — автоматически
включает оптимизацию, включая минимизацию и удаление неиспользуемого
кода.import/export ES6 модулей.Пример настройки минимизации в Webpack:
const TerserPlugin = require("terser-webpack-plugin");
module.exports = {
mode: "production",
optimization: {
minimize: true,
minimizer: [new TerserPlugin({
terserOptions: {
compress: { unused: true },
mangle: true,
},
})],
},
};Rollup Rollup изначально ориентирован на tree shaking. Он выполняет удаление неиспользуемого кода на этапе сборки, что делает его особенно эффективным для библиотек и приложений с модульной структурой.
Избегать динамических импортов там, где нужен строгий
анализ Динамические выражения типа
import(variable) могут быть полезны для ленивой загрузки
модулей, но они не участвуют в tree shaking, поскольку сборщик не знает
заранее, какой модуль будет импортирован.
Использовать named exports вместо default
export function funcA() {} позволяет сборщику точнее
определять использование кода. Default-экспорт часто приводит к
включению всего модуля целиком.
Проверка конечного бандла Lighthouse может анализировать производительность и размер финального бандла. Если tree shaking не сработал, отчёт покажет избыточные зависимости и мёртвый код.
Библиотеки и модульная совместимость
module поле в package.json).Lighthouse позволяет оценить, насколько эффективно применены методы оптимизации, включая tree shaking:
Неиспользуемый код внутри функций Tree shaking удаляет только неиспользуемые экспорты, но не может удалить мёртвый код внутри функций, если функция используется. Для этого нужно ручное рефакторингование или применение дополнительной минификации с dead code elimination.
Побочные эффекты (side effects) Если модуль
имеет побочные эффекты при импорте, сборщик не будет удалять его
полностью, чтобы не нарушить работу программы. Для Webpack это можно
контролировать через поле sideEffects в package.json:
{
"sideEffects": false
}Динамическая генерация экспорта Код типа
export const a = someCondition ? func1 : func2; может
мешать статическому анализу и снижать эффективность tree
shaking.
Эта методология позволяет создавать лёгкие и производительные приложения, сокращая объём загружаемых скриптов, ускоряя рендеринг страницы и упрощая поддержку кода. Tree shaking в связке с Lighthouse является ключевым инструментом для анализа и оптимизации фронтенд-проектов на JavaScript.