Lazy loading компонентов

Lazy loading (ленивая загрузка) компонентов — это техника оптимизации производительности React-приложений, позволяющая загружать части интерфейса только при их необходимости, а не сразу при загрузке страницы. В Chakra UI, которая является библиотекой компонентов для React с фокусом на доступность и стилизацию, lazy loading особенно полезен для больших приложений с множеством сложных UI-компонентов.


Использование React.lazy и Suspense

Chakra UI не предоставляет встроенного метода для ленивой загрузки компонентов, поэтому применяется стандартный механизм React — React.lazy совместно с Suspense.

Пример базовой реализации:

import React, { Suspense, lazy } from 'react';
import { Spinner, Box } from '@chakra-ui/react';

const LazyButton = lazy(() => import('./components/LazyButton'));

function App() {
  return (
    <Box p={4}>
      <Suspense fallback={<Spinner size="xl" />}>
        <LazyButton />
      </Suspense>
    </Box>
  );
}

export default App;

Пояснения:

  • React.lazy(() => import('./components/LazyButton')) — динамический импорт компонента. Код компонента загружается только при первом рендере.
  • Suspense используется для отображения placeholder (например, Spinner) во время загрузки компонента.
  • Chakra UI предоставляет удобные спиннеры (Spinner, CircularProgress), которые легко интегрируются в fallback.

Lazy Loading для нескольких компонентов

При работе с несколькими лениво загружаемыми компонентами важно избегать блокировки интерфейса. Для этого можно оборачивать каждый компонент в отдельный Suspense.

const LazyModal = lazy(() => import('./components/LazyModal'));
const LazyTable = lazy(() => import('./components/LazyTable'));

function Dashboard() {
  return (
    <Box p={6}>
      <Suspense fallback={<Spinner size="md" />}>
        <LazyModal />
      </Suspense>
      <Suspense fallback={<Spinner size="lg" />}>
        <LazyTable />
      </Suspense>
    </Box>
  );
}

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

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

Lazy Loading с Chakra UI модальными окнами и Drawer

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

const LazySettingsDrawer = lazy(() => import('./components/SettingsDrawer'));
import { Button, Drawer, DrawerOverlay, DrawerContent } from '@chakra-ui/react';
import { useState } from 'react';

function App() {
  const [isOpen, setIsOpen] = useState(false);

  return (
    <>
      <Button onCl ick={() => setIsOpen(true)}>Открыть настройки</Button>
      {isOpen && (
        <Suspense fallback={<Spinner />}>
          <LazySettingsDrawer onCl ose={() => setIsOpen(false)} />
        </Suspense>
      )}
    </>
  );
}

Преимущества такого подхода:

  • Компонент загружается только при открытии модального окна.
  • Первоначальная загрузка страницы остаётся быстрой, снижая время First Contentful Paint.
  • Suspense позволяет плавно показать индикатор загрузки, поддерживая UX на высоком уровне.

Chakra UI и динамические темы при ленивой загрузке

При использовании ChakraProvider с кастомными темами важно учитывать, что ленивые компоненты должны наследовать тему приложения. React.lazy не нарушает контекст, поэтому Chakra UI корректно применяет стили.

import { ChakraProvider, extendTheme } from '@chakra-ui/react';

const theme = extendTheme({
  colors: {
    brand: {
      100: '#f7caca',
      500: '#e53e3e',
    },
  },
});

function Root() {
  return (
    <ChakraProvider theme={theme}>
      <App />
    </ChakraProvider>
  );
}

Все ленивые компоненты, загружаемые внутри App, автоматически получат доступ к theme.


Советы по оптимизации

  1. Код-сплиттинг по страницам: Использовать ленивую загрузку для страниц или больших виджетов, чтобы уменьшить размер основного бандла.
  2. Скелетоны вместо спиннеров: Chakra UI предоставляет компоненты Skeleton и SkeletonText, которые визуально предсказывают форму загружаемого контента.
<Suspense fallback={<Skeleton height="40px" />}>
  <LazyCard />
</Suspense>
  1. Ленивая загрузка с React Router: Можно динамически импортировать компоненты маршрутов:
import { BrowserRouter as Router, Route, Routes } from 'react-router-dom';
const LazyHome = lazy(() => import('./pages/Home'));
const LazyAbout = lazy(() => import('./pages/About'));

function AppRouter() {
  return (
    <Router>
      <Suspense fallback={<Spinner />}>
        <Routes>
          <Route path="/" element={<LazyHome />} />
          <Route path="/about" element={<LazyAbout />} />
        </Routes>
      </Suspense>
    </Router>
  );
}
  1. Ленивая загрузка с Chakra UI Icons: Иконки можно тоже загружать динамически через React.lazy, что сокращает размер бандла при использовании множества иконок.

Заключение по практике Lazy Loading в Chakra UI

  • React.lazy и Suspense являются основной техникой ленивой загрузки.
  • Chakra UI предоставляет удобные компоненты Spinner, Skeleton, Drawer, Modal, которые органично интегрируются с ленивыми компонентами.
  • Ленивые компоненты ускоряют initial load, повышают отзывчивость интерфейса и экономят трафик.
  • Важно использовать отдельные Suspense для больших компонентов, чтобы не блокировать весь интерфейс.

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