Tree shaking
Tree shaking - это техника оптимизации JavaScript-кода, которая удаляет из финальной сборки неиспользуемые модули, функции, классы и переменные на этапе сборки, уменьшая размер бандла и ускоряя загрузку веб-приложения.
Техника используется разработчиками и фронтенд-командами для оптимизации размера бандла, улучшения скорости загрузки и прохождения Core Web Vitals. Например, разработчик импортирует библиотеку lodash, но использует только одну функцию cloneDeep(). Без tree shaking в итоговый файл попадает вся библиотека (70 КБ). С tree shaking - только код функции cloneDeep() (менее 1 КБ).
Tree shaking стал возможен с распространением ES-модулей (import/export) в 2015 году и последующей поддержкой в сборщиках. К 2026 году техника является стандартом для production-сборок во всех современных фреймворках (React, Vue, Angular, Svelte).
Простыми словами
[править]Tree shaking - это удаление «мёртвого» (неиспользуемого) кода при сборке JavaScript. Сборщик анализирует импорты и исключает всё, что не вызывается в приложении. Техника работает только с ES-модулями (import/export) и требует правильной настройки sideEffects.
Как работает tree shaking
[править]Tree shaking анализирует граф зависимостей на этапе сборки. Алгоритм проходит по всем импортам, отслеживает, какие экспорты реально используются, и исключает из сборки всё, что не имеет связей с точками входа приложения.
Процесс:
- Построение графа - сборщик (например, Webpack) строит граф зависимостей, начиная с точек входа (entry points).
- Анализ использования - сборщик анализирует, какие экспорты из каждого модуля действительно импортируются и используются.
- Маркировка - неиспользуемые экспорты помечаются как «мёртвый код».
- Удаление - на этапе минификации (например, через Terser) помеченный код удаляется.
Три главных условия для работы tree shaking:
- ES-модули (ESM) - код должен использовать современный синтаксис import и export. Старый формат require (CommonJS) не позволяет статически определить, что именно используется.
- Статический анализ - импорты должны быть статическими, без динамических условий.
- Side effects - необходимо указывать модули, которые имеют побочные эффекты (например, полифиллы), чтобы сборщик не удалял их ошибочно.
Пример настройки package.json
[править]Для корректной работы tree shaking необходимо указать поле sideEffects:
{
"name": "your-project",
"version": "1.0.0",
"sideEffects": false
}
Если в проекте есть файлы, которые нельзя удалять (например, CSS, полифиллы):
{
"sideEffects": [
"*.css",
"./src/polyfills.js"
]
}
Примеры использования
[править]- Импорт из UI-библиотеки (Ant Design, Material-UI) только нужных компонентов вместо всей библиотеки.
- Использование утилитарных библиотек (lodash, date-fns) с точечным импортом.
- Оптимизация бандла для SPA (Single Page Application) и лендингов.
- Уменьшение размера библиотек, распространяемых через npm.
Где используется
[править]| Сфера | Применение |
|---|---|
| JavaScript-проекты | Модульная архитектура с ES-модулями |
| Фронтенд-сборка | Webpack, Rollup, Vite, Parcel, esbuild |
| Библиотеки и npm-пакеты | Оптимизация потребления при импорте |
| Фреймворки | React, Vue, Angular, Svelte на этапе production-сборки |
Сравнение сборщиков по поддержке tree shaking
[править]| Сборщик | Поддержка | Особенности |
|---|---|---|
| Webpack | Отличная | Требует настройки optimization.usedExports и минификации через Terser |
| Rollup | Идеальная | Создан с фокусом на ES-модули, best-in-class для библиотек |
| Vite | Отличная | Использует Rollup для production-сборки |
| esbuild | Хорошая | Быстрый, но менее гибкий в настройке side effects |
| Parcel | Автоматическая | Работает из коробки, но меньше контроля |
Настройка tree shaking в Webpack
[править]Для корректной работы tree shaking в Webpack необходимо:
- Использовать ES-модули (type: "module" в package.json или import/export в коде).
- В package.json добавить "sideEffects": false, если в проекте нет модулей с побочными эффектами.
- В конфигурации Webpack:
module.exports = {
optimization: {
usedExports: true,
minimize: true
}
};
- Использовать минификатор (Terser), который удаляет мёртвый код.
Как проверить «вес» скриптов
[править]| Инструмент | Что показывает |
|---|---|
| Google PageSpeed Insights | Раздел «Устраните неиспользуемый код JavaScript» - список файлов с объёмом неиспользуемого кода |
| Chrome DevTools (Coverage) | Красные полоски - код, который скачался, но не выполнился |
| Webpack Bundle Analyzer | Интерактивная карта веса библиотек. Огромный квадрат lodash при использовании одной функции = tree shaking не настроен |
Связь с интернет-маркетингом
[править]Tree shaking напрямую влияет на бизнес-показатели через скорость загрузки сайта:
| Аспект | Влияние |
|---|---|
| SEO и Core Web Vitals | Удаление лишнего кода уменьшает время загрузки (LCP), улучшая позиции в Яндексе и Google |
| Показатель отказов (Bounce Rate) | Каждая секунда задержки на мобильных устройствах увеличивает отказ на 20 процентов. Меньше кода - быстрее загрузка - ниже отказы |
| CPA и ROAS | Тяжёлый код увеличивает стоимость целевого действия. Оптимизация через tree shaking снижает CPA |
| Сторонние скрипты | Чат-боты, пиксели, коллтрекинг должны поддерживать tree shaking, иначе они тормозят основной контент |
Преимущества
[править]- Уменьшение размера бандла - удаление неиспользуемого кода сокращает размер итоговых файлов.
- Ускорение загрузки - меньший размер -> быстрее загрузка и обработка в браузере.
- Улучшение Core Web Vitals - позитивно влияет на LCP и FCP.
- Экономия трафика - пользователи скачивают меньше данных.
- Упрощение поддержки - не нужно вручную удалять неиспользуемый код из проекта.
Недостатки
[править]- Зависимость от ES-модулей - не работает с CommonJS (require).
- Сложность с side effects - модули с побочными эффектами могут быть удалены ошибочно, если не настроить sideEffects: false.
- Ограниченная поддержка в библиотеках - не все npm-пакеты корректно поддерживают tree shaking.
- Настройка сборки - требует правильной конфигурации сборщика и минификатора.
Часто задаваемые вопросы
[править]Почему tree shaking не работает с require?
[править]CommonJS (require и module.exports) позволяет загружать модули динамически в любой момент выполнения кода. Сборщик не может статически определить, какие экспорты реально используются. ES-модули (import и export) статичны, что позволяет анализировать зависимости на этапе сборки.
Как проверить, работает ли tree shaking в проекте?
[править]Необходимо проанализировать сборку в Webpack Bundle Analyzer или вкладке Coverage в Chrome DevTools. Если в финальном бандле есть код, который не используется - tree shaking не настроен. Для development-режима с usedExports: true в консоли сборщика появится список неиспользуемых экспортов.
Что такое sideEffects в package.json?
[править]sideEffects - это поле, указывающее сборщику, какие файлы имеют побочные эффекты (например, полифиллы, глобальные стили, регистрации компонентов). Если установить "sideEffects": false, сборщик уверен, что любой неиспользуемый импорт можно безопасно удалить. Если указан массив файлов, они не удаляются даже при отсутствии явного использования.
Как tree shaking влияет на Core Web Vitals?
[править]Tree shaking уменьшает общий объём JavaScript-кода, что сокращает время загрузки (LCP) и время обработки скриптов (INP). Обе метрики входят в Core Web Vitals и влияют на ранжирование в Google.
Почему tree shaking важен для маркетолога?
[править]Tree shaking напрямую влияет на скорость загрузки сайта, а скорость - на SEO, конверсию и стоимость привлечения клиента. Чем меньше «мусора» в коде, тем выше прибыль с каждого зашедшего пользователя.
Почему tree shaking иногда не работает с библиотеками?
[править]Библиотека может быть собрана в формате CommonJS, иметь side effects без явного указания, или использовать динамические импорты. Для библиотек, распространяемых через npm, рекомендуется собирать их в ES-модулях ("./dist/index.mjs") и указывать sideEffects: false.
