Tree shaking и уменьшение бандла

Tree shaking — это процесс удаления неиспользуемого кода из финального бандла. В контексте Svelte и Carbon Components это критически важно, так как библиотека предоставляет большое количество компонентов, и подключение всех сразу приведёт к значительному росту размера сборки.

Принципы работы Tree shaking в Svelte

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

  1. Импорт конкретного компонента, а не всей библиотеки:

    // Плохо для Tree shaking
    import CarbonComponentsSvelte from 'carbon-components-svelte';
    
    // Хорошо для Tree shaking
    import Button from 'carbon-components-svelte/lib/Button/Button.svelte';

    Импорт по пути к конкретному компоненту позволяет сборщику (Vite, Rollup или Webpack) удалить неиспользуемые компоненты, так как они не участвуют в дереве зависимостей.

  2. Использование ES-модулей (ESM) Carbon Components Svelte предоставляет компоненты как ES-модули, что обеспечивает их поддержку Tree shaking. CommonJS модули не позволяют эффективно исключать неиспользуемый код.

Конфигурация сборщика для эффективного Tree shaking

  • Rollup: В rollup.config.js необходимо включить следующие параметры:

    import svelte from 'rollup-plugin-svelte';
    import resolve from '@rollup/plugin-node-resolve';
    import commonjs from '@rollup/plugin-commonjs';
    
    export default {
      input: 'src/main.js',
      output: {
        format: 'esm',
        dir: 'public/build'
      },
      plugins: [
        svelte(),
        resolve({
          browser: true,
          dedupe: ['svelte']
        }),
        commonjs(),
      ],
      treeshake: true
    };

    Ключевой момент — включение treeshake: true и работа с ESM.

  • Vite: Vite автоматически использует ES-модули и Rollup под капотом, но следует убедиться, что:

    optimizeDeps: {
      include: ['carbon-components-svelte/lib/Button/Button.svelte']
    }

    Не импортируются все компоненты целиком.

Стратегии уменьшения размера бандла

  1. Ленивая загрузка (Lazy loading) Использование динамического импорта позволяет загружать компоненты только при необходимости:

    let DialogComponent;
    async function loadDialog() {
        const module = await import('carbon-components-svelte/lib/Dialog/Dialog.svelte');
        DialogComponent = module.default;
    }

    Это снижает начальный размер бандла и ускоряет загрузку приложения.

  2. Удаление CSS для неиспользуемых компонентов Carbon Components Svelte поставляется с CSS для всех компонентов. При использовании Rollup или Vite можно импортировать только необходимые стили:

    // Импорт только стилей кнопки
    import 'carbon-components-svelte/lib/Button/button.css';

    Это предотвращает подключение лишних стилей, уменьшает вес CSS и повышает производительность.

  3. Минификация и сжатие Svelte автоматически минимизирует код при сборке в production. В дополнение, следует использовать:

    • terser для JS
    • cssnano для CSS Это дополнительно снижает размер бандла.

Анализ бандла

После настройки Tree shaking важно проверять результат:

  • Rollup Plugin Visualizer:

    import visualizer from 'rollup-plugin-visualizer';
    
    plugins: [
      visualizer({ filename: 'bundle-analysis.html' })
    ]

    Позволяет увидеть, какие компоненты занимают больше всего места.

  • Vite Bundle Analyzer:

    import { visualizer } from 'rollup-plugin-visualizer';
    export default {
      plugins: [visualizer({ open: true })]
    };

    Позволяет визуально оценить эффективность Tree shaking.

Оптимизация практическими методами

  • Импортировать компоненты только при необходимости.
  • Разделять приложение на ленивые чанки.
  • Подключать только нужные CSS-файлы.
  • Использовать производительные сборщики (Rollup, Vite) с поддержкой ESM.
  • Проверять бандл визуализаторами, чтобы убедиться в отсутствии «мертвого» кода.

Эти подходы позволяют Carbon Components Svelte оставаться лёгким и быстрым даже при большом количестве компонентов.

Если соблюдать эти правила, размер итогового бандла может уменьшиться в несколько раз без потери функциональности.