Ленивая загрузка компонентов

Ленивая загрузка (lazy loading) — это метод оптимизации производительности приложений, при котором компоненты загружаются только тогда, когда они реально нужны. В контексте Carbon Components Svelte, это позволяет уменьшить начальный размер бандла и ускорить рендеринг страницы.

Основы ленивой загрузки

В Svelte ленивую загрузку компонентов можно реализовать с помощью динамического импорта. Динамический импорт возвращает Promise, который разрешается модулем компонента. В сочетании с Carbon Components Svelte это выглядит следующим образом:

<script>
  import { onMount } from "svelte";

  let LazyComponent = null;
  let isLoading = true;

  onMount(async () => {
    const module = await import("@carbon/svelte/lib/SomeComponent.svelte");
    LazyComponent = module.default;
    isLoading = false;
  });
</script>

{#if isLoading}
  <p>Загрузка компонента...</p>
{:else}
  <svelte:component this={LazyComponent} />
{/if}

Ключевые моменты:

  • Используется import() для асинхронной загрузки.
  • svelte:component позволяет рендерить компонент, который определяется динамически.
  • Состояние загрузки (isLoading) необходимо для отображения плейсхолдера.

Интеграция с Carbon Components

Carbon Components Svelte состоит из множества UI-компонентов: кнопки, модальные окна, таблицы, формы и т.д. Ленивая загрузка особенно полезна для тяжёлых или редко используемых компонентов, таких как:

  • DataTable
  • Pagination
  • Modal
  • ComboBox

Пример ленивой загрузки DataTable:

<script>
  let TableComponent = null;
  let loading = true;

  async function loadTable() {
    const module = await import("@carbon/svelte/lib/DataTable/DataTable.svelte");
    TableComponent = module.default;
    loading = false;
  }
</script>

<button on:click={loadTable}>Показать таблицу</button>

{#if loading && TableComponent === null}
  <p>Таблица ещё не загружена.</p>
{:else if TableComponent}
  <svelte:component this={TableComponent} />
{/if}

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

  • Загрузка происходит по событию, что снижает нагрузку на главный бандл.
  • TableComponent === null помогает отличить «не загружено» от «загружается».

Совместимость с маршрутизаторами

При использовании Svelte с маршрутизаторами (например, svelte-routing или @sveltejs/kit) ленивые компоненты позволяют загружать страницы и UI только при переходе на соответствующий маршрут.

<script>
  import { Router, Route } from "svelte-routing";

  const routes = {
    "/": () => import("./Home.svelte"),
    "/dashboard": () => import("./Dashboard.svelte"),
  };
</script>

<Router>
  {#each Object.entries(routes) as [path, loader]}
    <Route path={path}>
      <AsyncRoute loader={loader} />
    </Route>
  {/each}
</Router>

<script>
  export let loader;
  let Component = null;

  onMount(async () => {
    const module = await loader();
    Component = module.default;
  });
</script>

{#if Component}
  <svelte:component this={Component} />
{:else}
  <p>Загрузка страницы...</p>
{/if}

Выводы по применению с маршрутизацией:

  • Маршруты не загружаются заранее, что уменьшает время первой загрузки.
  • Использование отдельного компонента-обёртки AsyncRoute упрощает управление состоянием загрузки и ошибок.

Оптимизация ленивой загрузки

  1. Разделение на маленькие компоненты: вместо загрузки больших модулей лучше разбивать их на части.
  2. Плейсхолдеры и скелетоны: Carbon Components Svelte предоставляет SkeletonText, SkeletonPlaceholder, которые создают эффект прогрузки.
  3. Ошибка загрузки: всегда следует обрабатывать ошибки при динамическом импорте, чтобы не ломался интерфейс:
try {
  const module = await import("@carbon/svelte/lib/Modal/Modal.svelte");
  LazyModal = module.default;
} catch (err) {
  console.error("Не удалось загрузить компонент:", err);
}

Использование с серверным рендерингом

При применении SvelteKit или других SSR-фреймворков необходимо учитывать, что динамический импорт выполняется только на клиенте. Поэтому код ленивой загрузки должен быть обёрнут проверкой browser:

import { browser } from '$app/environment';

if (browser) {
  const module = await import("@carbon/svelte/lib/ComboBox/ComboBox.svelte");
  ComboBox = module.default;
}

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

  • Модальные окна: загружать только при открытии, так как они редко используются.
  • Таблицы с фильтрацией: тяжелые DataTable и Pagination подгружаются только при переходе на страницу со статистикой.
  • Всплывающие подсказки и уведомления: маленькие UI-компоненты можно загрузить вместе с главной страницей, но сложные виджеты лучше лениво.

Рекомендации

  • Для масштабных приложений ленивые компоненты значительно сокращают время загрузки и повышают отзывчивость интерфейса.
  • Совместимость с Carbon Components Svelte не требует изменений API компонентов — динамический импорт полностью сохраняет свойства и события компонентов.
  • Комбинировать с SvelteKit load-функциями можно для предварительной загрузки данных до рендеринга компонента.

Ленивая загрузка становится эффективным инструментом оптимизации, особенно в сочетании с Carbon Components Svelte, где количество UI-компонентов и их сложность может быть значительным.