Performance best practices

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

Использование shouldForwardProp и chakra

Компонент chakra позволяет оборачивать обычные HTML-элементы или компоненты React, добавляя стили через props. Однако при неаккуратном использовании props могут передаваться ненужные атрибуты в DOM, что снижает производительность. Для предотвращения этого применяется функция shouldForwardProp:

import { chakra, shouldForwardProp } from "@chakra-ui/react";
import { isPropValid } from "@emotion/is-prop-valid";

const Box = chakra("div", {
  shouldForwardProp: (prop) => isPropValid(prop) && prop !== "myCustomProp",
});

Фильтрация props помогает уменьшить количество ненужных атрибутов в DOM и снижает нагрузку на рендерер.

Использование memo и React.forwardRef

Для компонентов, которые часто рендерятся с одинаковыми props, рекомендуется использовать React.memo. Это предотвращает повторный рендер при неизменных свойствах:

import { Box } from "@chakra-ui/react";
import React from "react";

const MemoizedBox = React.memo((props) => <Box {...props} />);

Если компонент использует ref, необходимо сочетать React.forwardRef с React.memo для сохранения производительности и правильной работы рефов:

const Button = React.memo(
  React.forwardRef((props, ref) => <chakra.button ref={ref} {...props} />)
);

Стилизация через sx и styleConfig

Chakra UI поддерживает несколько способов стилизации: props, sx и styleConfig. Использование sx позволяет объединять стили на уровне компонента и уменьшает количество создаваемых объектов стилей при каждом рендере:

<Box
  sx={{
    display: "flex",
    alignItems: "center",
    justifyContent: "space-between",
  }}
/>

Для больших библиотек компонентов предпочтительно использовать extendTheme и styleConfig, чтобы вынести стили за пределы компонента и не пересоздавать их при каждом рендере.

Lazy loading и динамический импорт компонентов

Для страниц с большим количеством модальных окон, таблиц или других тяжёлых компонентов важно использовать динамический импорт через React lazy и Suspense:

import React, { Suspense, lazy } from "react";

const LazyModal = lazy(() => import("./Modal"));

function App() {
  return (
    <Suspense fallback={<div>Загрузка...</div>}>
      <LazyModal />
    </Suspense>
  );
}

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

Избегание лишних перерисовок при использовании useStyleConfig

useStyleConfig позволяет получать предопределённые стили темы для компонента. При каждом вызове хука создается новый объект стилей, что может привести к лишним рендерингам. Для оптимизации следует:

  • Использовать мемоизацию через React.useMemo
  • Вынести вызов хука за пределы часто рендерящихся компонентов
const buttonStyles = useMemo(() => useStyleConfig("Button", { variant: "solid" }), []);

Оптимизация Grid и Flex-компонентов

Компоненты Grid и Flex широко применяются для построения интерфейса. Для производительности:

  • Ограничивать количество вложенных Flex/Grid
  • Использовать templateColumns и templateRows вместо множества вложенных компонентов
  • Применять shouldWrapChildren и wrap аккуратно
<Grid templateColumns="repeat(3, 1fr)" gap={4}>
  {items.map(item => <Box key={item.id}>{item.name}</Box>)}
</Grid>

Важность chakra + системных props вместо inline-style

Системные props (p, m, bg, color, fontSize) компилируются в классы CSS при построении приложения, что эффективнее, чем inline-style для большого количества компонентов.

<Box p={4} bg="gray.100" color="black">
  Контент
</Box>

Использование системных props уменьшает объём создаваемого CSS в runtime и снижает нагрузку на рендер.

Оптимизация тем и глобальных стилей

Тема Chakra UI должна быть спроектирована так, чтобы повторно используемые цвета, размеры и шрифты были вынесены в theme.tokens. Это позволяет использовать одни и те же объекты вместо создания новых на каждом рендере:

const theme = extendTheme({
  colors: {
    brand: {
      100: "#f7fafc",
      500: "#2b6cb0",
    },
  },
});

Использование токенов делает стили предсказуемыми и минимизирует дублирование объектов.

Использование shouldUsePortal и closeOnEsc в модальных компонентах

Компоненты типа Modal и Popover создают портал в DOM. Для оптимизации:

  • Не рендерить модальные окна, пока они не нужны (isOpen lazy load)
  • Использовать closeOnEsc и closeOnOverlayClick для контроля рендеринга
<Modal isOpen={isOpen} onCl ose={onClose} closeOnOverlayClick={true}>
  <ModalContent>...</ModalContent>
</Modal>

Заключение по практикам

Ключевыми подходами для высокой производительности Chakra UI являются:

  • Меморизация компонентов и стилей
  • Использование системных props вместо inline-style
  • Динамический импорт тяжелых компонентов
  • Оптимизация Grid и Flex-структур
  • Вынесение тем и конфигураций стилей за пределы рендерящихся компонентов

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