Bundle size сравнение

Размер итогового бандла напрямую влияет на скорость загрузки, время до первого рендера, потребление памяти и общую отзывчивость интерфейса. Для компонентных фреймворков, ориентированных на переиспользуемые UI-библиотеки, bundle size становится критическим параметром. Stencil изначально проектировался как инструмент для создания лёгких Web Components, и архитектурные решения фреймворка отражаются на размере собираемого кода.

Архитектурные предпосылки минимального размера в Stencil

Stencil не является рантайм-фреймворком в классическом смысле. Он представляет собой компилятор, который на этапе сборки:

  • анализирует компоненты,
  • удаляет неиспользуемый код,
  • генерирует оптимизированный JavaScript без необходимости подключения тяжёлого runtime.

Ключевые особенности, влияющие на размер бандла:

  • Compile-time подход — большая часть логики фреймворка не попадает в итоговый бандл.
  • Tree Shaking по умолчанию — каждый компонент компилируется изолированно.
  • Отсутствие виртуального DOM как обязательного слоя — используется минимальный diffing и прямое обновление DOM.
  • Ленивая загрузка компонентов — каждый компонент может быть отдельным чанком.

Структура бандлов, генерируемых Stencil

Stencil генерирует несколько типов выходных файлов, каждый из которых играет свою роль:

  • loader — минимальный загрузчик компонентов (несколько килобайт).
  • core runtime — общий код, используемый всеми компонентами (обычно 6–10 KB gzip).
  • component bundles — код конкретных компонентов, загружаемых по требованию.

Такой подход принципиально отличается от монолитных бандлов, характерных для SPA-фреймворков.

Сравнение с React

React-приложение даже минимальной сложности включает:

  • react
  • react-dom
  • вспомогательные абстракции (hooks, reconciler)

Типичные цифры:

  • React + React DOM: ~42 KB gzip
  • С учётом базовой инфраструктуры: 60–70 KB gzip

Stencil-библиотека с аналогичным набором UI-компонентов:

  • loader + runtime: ~8–12 KB gzip
  • каждый компонент: от 0.5 до 3 KB gzip

Ключевое отличие заключается в том, что React требует загрузки всего ядра сразу, тогда как Stencil загружает только используемые компоненты.

Сравнение с Angular

Angular ориентирован на масштабные приложения и включает в себя:

  • dependency injection контейнер,
  • шаблонизатор,
  • change detection,
  • RxJS как обязательную зависимость.

Даже оптимизированный production-бандл Angular редко опускается ниже:

  • 120–150 KB gzip для минимального приложения.

Stencil не включает DI, RxJS или глобальный механизм change detection, что радикально снижает объём итогового кода.

Сравнение с Vue

Vue 3 значительно улучшил показатели bundle size за счёт tree shaking и compiler-based архитектуры:

  • Vue runtime core: ~20 KB gzip
  • С приложением среднего размера: 30–40 KB gzip

Stencil при аналогичном сценарии (набор независимых компонентов без SPA-обвязки):

  • runtime: ~8 KB gzip
  • суммарный размер загруженных компонентов зависит от фактического использования.

При использовании Stencil как библиотеки компонентов для разных проектов Vue, React или plain JS выгода по размеру становится особенно заметной.

Bundle size и Web Components

Stencil генерирует нативные Web Components без прокси-слоёв. Это означает:

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

Для дизайн-систем и UI-китов это снижает совокупный bundle size экосистемы в разы.

Влияние lazy loading на итоговый объём

Stencil по умолчанию применяет ленивую загрузку:

  • компонент загружается только при первом появлении в DOM,
  • браузер не загружает неиспользуемые чанки,
  • initial bundle остаётся минимальным.

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

Контроль размера на уровне конфигурации

Stencil предоставляет механизмы дополнительной оптимизации:

  • отключение legacy-поддержки (buildEs5: false),
  • исключение polyfills для современных браузеров,
  • разделение output targets (ESM, lazy, hydrate).

Каждый из этих параметров напрямую уменьшает размер итогового JavaScript.

Практические сценарии сравнения

UI-библиотека для нескольких фреймворков

  • React-реализация: отдельные сборки под React, Vue, Angular.
  • Stencil-реализация: одна сборка Web Components.

Итоговый суммарный размер для всей экосистемы при использовании Stencil оказывается существенно ниже.

Микрофронтенды

Stencil хорошо вписывается в микрофронтенд-архитектуру:

  • отсутствие глобального runtime,
  • независимые чанки,
  • минимальный конфликт зависимостей.

Каждый микрофронтенд загружает только собственные компоненты без повторной загрузки фреймворка.

Ограничения и компромиссы

Минимальный bundle size достигается за счёт:

  • отсутствия встроенного роутинга,
  • отсутствия глобального state-менеджмента,
  • ограниченного набора высокоуровневых абстракций.

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

Итоговые наблюдения по сравнению размеров

  • Stencil показывает один из наименьших размеров runtime среди популярных решений.
  • Основное преимущество проявляется в библиотечном и кросс-фреймворковом использовании.
  • При равной функциональности итоговый объём JavaScript почти всегда меньше, чем у SPA-фреймворков.
  • Bundle size в Stencil масштабируется линейно от фактически используемых компонентов, а не от возможностей фреймворка.