Common chunks

Common chunks — это механизм оптимизации сборки, который позволяет выделять общий код, используемый в нескольких компонентах, в отдельные файлы. В контексте Stencil это особенно важно, так как фреймворк ориентирован на создание веб-компонентов с высокой степенью переиспользования и минимизацией размера бандла для ускорения загрузки.


Принцип работы

Stencil использует Rollup под капотом для сборки компонентов. Rollup автоматически анализирует зависимости между модулями и определяет участки кода, которые повторяются. Эти повторяющиеся фрагменты выносятся в отдельные чанки. Такой подход снижает общий размер JavaScript, загружаемого при использовании нескольких компонентов на одной странице.

Основные преимущества:

  • Меньше дублирования кода: общий функционал не вставляется в каждый компонент, а подключается через отдельный файл.
  • Повышение производительности: браузеру нужно загружать меньше кода при переходе между страницами или использованием различных компонентов.
  • Кэширование: отдельные чанки можно эффективно кэшировать, что сокращает время повторной загрузки.

Настройка в Stencil

Stencil позволяет управлять формированием общих чанков через конфигурацию проекта (stencil.config.ts). Основные параметры:

import { Config } from '@stencil/core';

export const config: Config = {
  namespace: 'mycomponents',
  outputTargets: [
    {
      type: 'dist',
      esmLoaderPath: '../loader',
      dir: 'dist/components'
    }
  ],
  buildEs5: false,
  commonjs: {
    include: ['some-external-lib']
  }
};
  • namespace — уникальное пространство имён компонентов. Используется для генерации глобальных файлов и common chunks.
  • outputTargets — определяет, куда будет помещён результат сборки. Common chunks создаются в рамках этого пути.
  • commonjs.include — список модулей, которые нужно включить в обработку для объединения в общие чанки.

Динамическое создание чанков

Stencil автоматически создаёт чанки для динамически импортируемых компонентов. Например:

@Component({
  tag: 'lazy-component',
  styleUrl: 'lazy-component.css',
  shadow: true
})
export class LazyComponent {
  async loadExtra() {
    const module = await import('./extra-module');
    module.init();
  }
}

Здесь extra-module будет вынесен в отдельный файл при сборке, а основной бандл останется минимальным. Браузер загрузит модуль только при вызове loadExtra.


Оптимизация количества чанков

Иногда при использовании большого количества компонентов автоматически создаются слишком мелкие файлы, что может негативно повлиять на производительность из-за множества HTTP-запросов. Для решения:

  • Объединение компонентов в группы: компоненты, часто используемые вместе, можно собрать в один модуль, уменьшив количество чанков.
  • Внешние зависимости: подключение сторонних библиотек через commonjs.include позволяет исключить повторное включение одной и той же логики.
  • Lazy Loading только для редких компонентов: те части, которые не нужны сразу, стоит загружать асинхронно, чтобы основной бандл оставался лёгким.

Анализ чанков

Stencil предоставляет инструменты для анализа структуры бандлов и чанков:

stencil build --dev --stats

Результат — JSON-файл с информацией о каждом модуле, его размере и том, какие чанки зависят от него. Это позволяет:

  • Определять модули с большим дублированием.
  • Настраивать lazy loading для редко используемых компонентов.
  • Выявлять возможности для объединения или разделения кода.

Рекомендации по использованию

  • Выносить повторяющиеся утилиты, функции и стили в отдельные модули для автоматического формирования общих чанков.
  • Минимизировать использование больших библиотек в отдельных компонентах — лучше подключать их через common chunks.
  • Для проектов с большим количеством компонентов использовать стратегию lazy loading для редко используемых модулей.
  • Периодически анализировать бандлы с помощью --stats для контроля размера и эффективности чанков.

Итоговые практики

Common chunks — это ключевой инструмент оптимизации производительности Stencil-приложений. Они позволяют минимизировать размер бандла, снизить нагрузку на сеть и ускорить загрузку компонентов. Правильное распределение кода между основным бандлом и чанками критично для проектов с большим количеством компонентов и сторонних библиотек.

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