Code splitting

Code splitting — это техника оптимизации веб-приложений, позволяющая разбивать код на отдельные части, которые загружаются по мере необходимости. В контексте библиотеки Haunted, которая строится поверх Web Components и использует реактивные хуки, правильное применение code splitting позволяет значительно снизить первоначальный размер бандла и ускорить загрузку страниц.


Динамический импорт компонентов

В Haunted компоненты создаются через функцию html и хуки, такие как useState, useEffect, useReducer. Для разделения кода важно использовать динамический импорт, который возвращает Promise с модулем:

import { html, render } from 'haunted';

const loadComponent = () => import('./MyComponent.js');

const app = async () => {
  const module = await loadComponent();
  const MyComponent = module.default;

  render(html`<${MyComponent}></${MyComponent}>`, document.body);
};

app();

Здесь MyComponent.js загружается только тогда, когда вызывается loadComponent. Такой подход позволяет не включать весь код сразу в основной бандл.


Использование Webpack или Vite

Для полноценного code splitting важно настроить сборщик. Например, в Webpack:

entry: './index.js',
output: {
  filename: '[name].bundle.js',
  chunkFilename: '[name].chunk.js',
  path: path.resolve(__dirname, 'dist'),
},
optimization: {
  splitChunks: {
    chunks: 'all',
  },
},
  • filename — основной бандл;
  • chunkFilename — отдельные чанки, создаваемые при динамическом импорте;
  • splitChunks с chunks: 'all' позволяет автоматически разбивать зависимости, используемые в разных местах.

В Vite достаточно динамического импорта, так как сборщик сам создает отдельные чанки:

const MyLazyComponent = () => import('./components/MyLazyComponent.js');

Haunted-компоненты, загружаемые таким образом, автоматически работают с Vite-подходом к ленивой загрузке.


Асинхронные компоненты

Haunted не имеет встроенного механизма ленивой загрузки компонентов, как React Suspense, но можно создать собственный паттерн асинхронного компонента:

import { html, component } from 'haunted';

function AsyncComponent({ loader }) {
  const [Comp, setComp] = useState(null);

  useEffect(() => {
    loader().then(module => setComp(module.default));
  }, [loader]);

  return Comp ? html`<${Comp}></${Comp}>` : html`<p>Загрузка...</p>`;
}

customElements.define('async-component', component(AsyncComponent));

Пример использования:

html`<async-component .loader=${() => import('./MyComponent.js')}></async-component>`

Паттерн позволяет показывать индикатор загрузки, пока компонент динамически подгружается, и полностью совместим с реактивными хуками Haunted.


Оптимизация зависимостей

При использовании code splitting важно учитывать:

  • Общие зависимости: библиотеки вроде lit-html или haunted можно вынести в отдельный бандл vendor. Это уменьшает повторную загрузку при смене страниц.
  • Статические ассеты: изображения, стили, шрифты также лучше загружать лениво через динамический импорт или fetch.
  • Размер компонентов: компоненты с большим количеством кода или сторонними библиотеками особенно выгодно загружать асинхронно.

Сценарии применения

  1. Маршрутизация: каждый роут загружает свой компонент по мере необходимости.
  2. Редкие модальные окна или виджеты: heavy-компоненты, которые открываются не на каждой странице.
  3. Плагинная архитектура: когда набор компонентов не фиксирован, а расширяется динамически.

Особенности Haunted

  • Haunted строится на Web Components, поэтому компоненты можно регистрировать и рендерить только после загрузки кода.
  • Хуки остаются полностью рабочими в ленивых компонентах: useState, useEffect, useReducer корректно инициализируются после подгрузки.
  • Разделение кода не влияет на реактивность: изменения состояний компонента продолжают обновлять DOM через html шаблоны.

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

  • Всегда использовать динамический импорт для больших компонентов.
  • Включать индикаторы загрузки для улучшения UX.
  • Выносить общие библиотеки в отдельный бандл.
  • Тестировать производительность: иногда слишком мелкие чанки могут увеличивать количество запросов и замедлять загрузку.
  • Совмещать code splitting с lazy CSS loading, если компонент содержит тяжелые стили.

Применение code splitting в Haunted позволяет строить масштабируемые приложения, минимизировать время первичной загрузки и поддерживать реактивность компонентов без дополнительных сложных паттернов. Правильная организация динамических импортов и асинхронных компонентов превращает обычные веб-компоненты в гибкие, модульные блоки, готовые к ленивой загрузке и оптимизации ресурсов.