Настройка SSR

Ant Design (AntD) — это популярная библиотека компонентов для React, которая предлагает готовые элементы интерфейса с продуманной стилистикой и функциональностью. При использовании серверного рендеринга (SSR, Server-Side Rendering) необходимо учитывать особенности работы стилей и компонентов AntD, чтобы корректно отображать интерфейс как на сервере, так и на клиенте.


Импорт и настройка стилей

Ant Design использует Less для генерации CSS, что требует особого подхода при SSR. Для корректного рендеринга необходимо импортировать стили таким образом, чтобы сервер мог их обработать.

Пример базовой конфигурации:

import React from 'react';
import ReactDOMServer from 'react-dom/server';
import { ConfigProvider } from 'antd';
import App from './App';
import 'antd/dist/antd.css'; // Базовые стили

При использовании Next.js или аналогичных фреймворков рекомендуется подключать стили глобально через _app.js или аналогичный корневой файл. Это предотвращает проблемы с отсутствием CSS при серверном рендеринге.


Использование ConfigProvider для SSR

Компонент ConfigProvider позволяет задать глобальные настройки AntD: локализацию, тему и поведение компонентов. При SSR важно передавать одинаковую конфигурацию на сервере и клиенте.

import ruRU from 'antd/locale/ru_RU';

const app = (
  <ConfigProvider locale={ruRU}>
    <App />
  </ConfigProvider>
);

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

  • locale — определяет язык компонентов (например, календарей, сообщений, кнопок).
  • prefixCls — позволяет изменять префикс CSS-классов, что полезно при интеграции с CSS Modules или другими системами.

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

Next.js предоставляет встроенную поддержку SSR, но AntD требует особой обработки стилей. Для корректного рендеринга используется библиотека @next/bundle-analyzer или кастомизация _document.js.

Пример настройки _document.js:

import Document, { Html, Head, Main, NextScript } from 'next/document';
import { ServerStyleSheet } from 'styled-components';
import { extractStyle } from 'antd/dist/antd.css';

class MyDocument extends Document {
  static async getInitialProps(ctx) {
    const sheet = new ServerStyleSheet();
    const originalRenderPage = ctx.renderPage;

    try {
      ctx.renderPage = () =>
        originalRenderPage({
          enhanceApp: (App) => (props) =>
            sheet.collectStyles(<App {...props} />),
        });

      const initialProps = await Document.getInitialProps(ctx);
      return {
        ...initialProps,
        styles: (
          <>
            {initialProps.styles}
            {sheet.getStyleElement()}
            <style dangerouslySetInnerHTML={{ __html: extractStyle() }} />
          </>
        ),
      };
    } finally {
      sheet.seal();
    }
  }

  render() {
    return (
      <Html>
        <Head />
        <body>
          <Main />
          <NextScript />
        </body>
      </Html>
    );
  }
}

export default MyDocument;

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

  • ServerStyleSheet собирает стили при рендеринге на сервере.
  • extractStyle обеспечивает корректное подключение CSS AntD.
  • dangerouslySetInnerHTML используется только для инлайн-стилей, полученных с сервера, чтобы избежать FOUC (flash of unstyled content).

Работа с компонентами, зависящими от браузера

Некоторые компоненты AntD (например, DatePicker, Carousel) используют объекты window или document. При SSR их рендерить на сервере нельзя.

Решения:

  1. Динамический импорт с отключением SSR:
import dynamic from 'next/dynamic';

const DatePickerNoSSR = dynamic(() => import('antd').then(mod => mod.DatePicker), {
  ssr: false,
});
  1. Проверка наличия window перед использованием:
const isBrowser = typeof window !== 'undefined';

return isBrowser ? <DatePicker /> : null;

Настройка темы и переменных Less при SSR

AntD позволяет кастомизировать тему через Less-переменные. Для SSR важно правильно передавать эти переменные на сервер, чтобы цвета и размеры совпадали с клиентской частью.

Пример с Next.js и next-plugin-antd-less:

// next.config.js
const withAntdLess = require('next-plugin-antd-less');

module.exports = withAntdLess({
  modifyVars: { '@primary-color': '#1DA57A' },
  lessVarsFilePath: './src/styles/variables.less',
  webpack(config) {
    return config;
  },
});

Преимущества:

  • Единая тема на сервере и клиенте.
  • Поддержка динамических цветов и dark/light режимов.

Оптимизация производительности

При SSR важно минимизировать время генерации страниц:

  • Импортировать только необходимые компоненты, а не всю библиотеку AntD.
  • Использовать babel-plugin-import для автоматического tree-shaking:
// babel.config.js
module.exports = {
  plugins: [
    [
      'import',
      { libraryName: 'antd', libraryDirectory: 'es', style: 'css' },
    ],
  ],
};
  • Собирать и кешировать стили на сервере.
  • Использовать React.memo для компонентов с частыми ререндерингами.

Обработка глобальных стилей и CSS-модулей

При SSR рекомендуется избегать конфликта стилей:

  • Использовать prefixCls в ConfigProvider для изоляции классов AntD.
  • Подключать пользовательские CSS после базовых стилей AntD.
  • Для CSS-модулей импортировать .module.css или .module.less и применять локальные классы.

Особенности работы с модальными окнами и порталом

Компоненты Modal, Tooltip, Dropdown используют портал (React Portal) для рендеринга поверх DOM. При SSR необходимо:

  • Убедиться, что целевой контейнер (document.body) существует.
  • Использовать getContainer={typeof window !== 'undefined' ? () => document.body : undefined}.
  • Динамически загружать компоненты при рендеринге на клиенте.

Итоговые рекомендации по SSR с Ant Design

  • Всегда синхронизировать темы и локали между сервером и клиентом.
  • Подключать стили через глобальный импорт или специализированные плагины.
  • Динамически загружать компоненты, зависящие от браузера.
  • Минимизировать объём стилей через tree-shaking и babel-plugin-import.
  • Контролировать рендеринг порталов и компонентов с зависимостями от window/document.

Эти подходы обеспечивают корректный рендеринг интерфейса, предотвращают FOUC и повышают производительность при использовании Ant Design с SSR.