Гидратация стилей

Ant Design использует систему стилей на основе CSS-in-JS, что позволяет динамически управлять темами и изменять визуальное оформление компонентов на лету. Гидратация стилей — процесс, при котором стили, сгенерированные на сервере или при первоначальной загрузке страницы, синхронизируются с клиентской частью, чтобы избежать конфликтов и лишнего рендеринга.

Гидратация особенно критична для серверного рендеринга (SSR) в приложениях на React, где Ant Design используется вместе с библиотеками вроде Next.js. Без правильной гидратации стили могут мигрировать, дублироваться или полностью исчезать при первом рендере на клиенте.


Работа с CSS-in-JS в Ant Design

Ant Design использует @ant-design/cssinjs для управления стилями компонентов. Каждый компонент поставляется с собственной системой генерации CSS, которая привязана к уникальному идентификатору. Это предотвращает коллизии классов и обеспечивает корректное применение тем.

Принципы работы гидратации стилей:

  1. Генерация стилей на сервере: при SSR стили компонентов собираются и добавляются в HTML, который отправляется клиенту.
  2. Сбор идентификаторов стилей: уникальные ключи, которые связывают сгенерированные классы с компонентами.
  3. Гидратация на клиенте: после загрузки HTML клиентская часть React повторно «подхватывает» эти стили, не генерируя их заново.

В Ant Design для этого используется компонент <StyleProvider> и API useCacheToken.


Использование <ConfigProvider> и <StyleProvider>

<ConfigProvider> отвечает за глобальные настройки Ant Design, включая локализацию, тему и управление форматом компонентов. Для корректной гидратации стилей важно обернуть приложение в <StyleProvider> с указанием свойства ssrInline или cache:

import React from 'react';
import { ConfigProvider, theme, StyleProvider } from 'antd';
import { createCache } from '@emotion/cache';

const cache = createCache({ key: 'antd' });

function App({ children }) {
  return (
    <StyleProvider cache={cache}>
      <ConfigProvider theme={theme.defaultAlgorithm}>
        {children}
      </ConfigProvider>
    </StyleProvider>
  );
}

Здесь createCache создает единый контейнер для всех стилей, что обеспечивает их правильную гидратацию и предотвращает дублирование CSS.


Работа с токенами темизации

Ant Design 5 использует систему токенов для темы, позволяя управлять цветами, отступами, типографикой и другими визуальными параметрами динамически. Токены можно настраивать глобально или на уровне компонента через useToken:

import { theme } from 'antd';

const { useToken } = theme;

function ButtonExample() {
  const { token } = useToken();
  return (
    <button style={{ backgroundColor: token.colorPrimary, padding: token.padding }}>
      Кнопка с токенами
    </button>
  );
}

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


Оптимизация гидратации для больших приложений

В больших проектах с множеством компонентов важно контролировать порядок и количество вставки стилей. Несколько рекомендаций:

  1. Использовать единый StyleProvider для всего приложения.
  2. Кэшировать токены темы и переиспользовать их, чтобы не пересоздавать объект токенов при каждом рендере.
  3. Избегать двойной гидратации: при SSR не вставлять стили вручную в <head>, полагаясь на встроенные механизмы Ant Design.
  4. Асинхронная загрузка компонентов: при код-сплиттинге убедиться, что динамически импортированные компоненты получают доступ к уже гидратированным стилям.

Проблемы и отладка

Наиболее частые ошибки при гидратации стилей:

  • Миграция стилей при первом рендере — вызвана отсутствием кэша или неправильной конфигурацией StyleProvider.
  • Дублирование CSS — появляется, если на клиенте генерируются новые классы поверх уже встроенных стилей.
  • Несовпадение темы — возникает, если токены темы создаются отдельно на сервере и на клиенте.

Для отладки рекомендуется использовать DevTools и проверять:

  • наличие всех CSS-классов в <head>,
  • совпадение ключей (data-cache-key) у стилей,
  • корректное применение токенов.

Интеграция с Next.js

Для Next.js процесс гидратации включает:

  1. Сбор стилей с помощью renderToString или renderToStaticMarkup.
  2. Передача стилей в HTML через getInitialProps.
  3. Повторное использование кэша на клиенте для предотвращения дублирования.

Пример для _document.js:

import Document, { Html, Head, Main, NextScript } from 'next/document';
import { extractStyle } from '@ant-design/cssinjs';

export default class MyDocument extends Document {
  static async getInitialProps(ctx) {
    const initialProps = await Document.getInitialProps(ctx);
    const styles = extractStyle();
    return { ...initialProps, styles };
  }

  render() {
    return (
      <Html>
        <Head>{this.props.styles}</Head>
        <body>
          <Main />
          <NextScript />
        </body>
      </Html>
    );
  }
}

Это гарантирует, что стили компонентов Ant Design рендерятся на сервере и правильно гидратируются на клиенте.


Итоговые ключевые моменты

  • Гидратация стилей предотвращает миграцию и дублирование CSS при SSR.
  • Использование <StyleProvider> с единым кэшем является обязательным для больших приложений.
  • Токены темы нужно рассчитывать один раз и передавать как на сервер, так и на клиент.
  • Контроль порядка генерации и вставки стилей позволяет избежать конфликтов и несоответствий интерфейса.