Tree shaking

Tree shaking — это процесс оптимизации JavaScript-кода, при котором ненужные экспорты модулей удаляются из итогового бандла. В случае с Tippy.js эта техника особенно полезна, так как библиотека предоставляет множество функциональных возможностей, из которых могут использоваться лишь некоторые. Правильное применение tree shaking позволяет уменьшить размер финального скрипта и повысить производительность веб-приложения.


Модульная структура Tippy.js

Tippy.js изначально разработан с поддержкой ES Modules (ESM). Основные модули включают:

  • tippy.js – основной функционал для создания тултипов.
  • tippy.js/animations – набор предустановленных анимаций.
  • tippy.js/themes – стили и темы для тултипов.
  • tippy.js/dist – скомпилированные версии для CommonJS и UMD.

Использование ESM позволяет современным сборщикам, таким как Webpack и Rollup, эффективно выполнять tree shaking, удаляя ненужные модули и функции.


Импорт только необходимых функций

Стандартный импорт всей библиотеки:

import tippy from 'tippy.js';
import 'tippy.js/dist/tippy.css';

Этот подход подключает весь функционал библиотеки, включая анимации и темы, даже если они не используются. Для минимизации веса скрипта применяется модульный импорт:

import tippy from 'tippy.js';
import 'tippy.js/dist/tippy.css';

tippy('.btn', {
  content: 'Tooltip example',
});

Если нужны только определенные анимации:

import { fade } from 'tippy.js/animations';

tippy('.btn', {
  content: 'Fade tooltip',
  animation: fade,
});

Использование именованного импорта гарантирует, что ненужные анимации не попадут в финальный бандл.


Настройка сборщика для tree shaking

Webpack: Для эффективного tree shaking важно использовать production mode и ESM-пакеты. В webpack.config.js это настраивается через:

module.exports = {
  mode: 'production',
  optimization: {
    usedExports: true,
  },
};

Rollup: Rollup изначально ориентирован на ESM и выполняет tree shaking автоматически. Пример конфигурации:

import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';

export default {
  input: 'src/main.js',
  output: {
    file: 'dist/bundle.js',
    format: 'esm',
  },
  plugins: [resolve(), commonjs()],
};

Важно: для корректного удаления неиспользуемого кода библиотека должна предоставлять ES Module версии всех функций, что Tippy.js выполняет через ESM-экспорты.


Практические рекомендации

  1. Импортировать только то, что используется: анимации, плагины и темы подключаются отдельно.
  2. Избегать require и CommonJS при использовании tree shaking: ESM позволяет сборщику точно определить неиспользуемый код.
  3. Удалять глобальные импорты CSS, если используется кастомная стилизация: это снижает общий вес стилей.
  4. Следить за сторонними плагинами Tippy.js: подключение плагина автоматически добавляет весь функционал, даже если используется частично.

Пример оптимизированного кода с минимальным бандлом

import tippy from 'tippy.js';
import 'tippy.js/dist/tippy.css';
import { scale } from 'tippy.js/animations';
import { sticky } from 'tippy.js/plugins';

tippy('.tooltip', {
  content: 'Optimized tooltip',
  animation: scale,
  plugins: [sticky],
});

В этом примере:

  • Импортируется только базовый функционал Tippy.js.
  • Подключается только одна анимация (scale) и один плагин (sticky).
  • Остальной функционал библиотеки, включая другие анимации и темы, не попадает в итоговый бандл.

Контроль размера бандла

Для оценки влияния tree shaking на размер бандла используются инструменты:

  • Webpack Bundle Analyzer – визуализирует все модули и их вес.
  • Rollup Visualizer – показывает, какие функции включены в итоговый ESM-бандл.

Регулярная проверка позволяет убедиться, что ненужные функции Tippy.js не включаются и размер скрипта минимален.


Итоговые принципы

  • Использовать ESM версии Tippy.js.
  • Импортировать только необходимые функции и плагины.
  • Настроить сборщик для активного tree shaking.
  • Проверять итоговый бандл визуализаторами для контроля веса.

Tree shaking в Tippy.js обеспечивает значительное снижение размера бандла при сохранении всей необходимой функциональности и гибкости для современных веб-приложений.