JavaRush /Курсы /Модуль 3: React /Динамическая загрузка компонентов в Next.js с помощью nex...

Динамическая загрузка компонентов в Next.js с помощью next/dynamic

Модуль 3: React
14 уровень , 7 лекция
Открыта

Зачем нужна динамическая загрузка?

Когда приложение становится большим, важно оптимизировать его начальную загрузку. Мы не хотим тянуть весь JavaScript-код сразу, особенно если часть компонентов используется редко (например, модальные окна, графики, панели администрирования).

Ранее мы уже использовали React.lazy, который позволяет загружать компоненты только при необходимости. Но в Next.js, особенно когда вы используете SSR (Server-Side Rendering), React.lazy не работает на сервере.

Решение от Next.js — next/dynamic

Next.js предоставляет специальную функцию dynamic из модуля next/dynamic, которая позволяет вам:

  • Загружать компоненты динамически.
  • Контролировать SSR: включать или отключать его.
  • Добавлять фолбэк-компоненты (индикаторы загрузки).
  • Работать с типами и default/именованными экспортами

Базовое использование next/dynamic

import dynamic from 'next/dynamic';

const HeavyComponent = dynamic(() => import('./HeavyComponent'));

export default function HomePage() {
  return (
    <div>
      <h1>Главная страница</h1>
      <HeavyComponent />
    </div>
  );
}

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

Добавляем loading (fallback)

Чтобы показать, что компонент загружается, можно передать опцию loading:

const HeavyComponent = dynamic(() => import('./HeavyComponent'), {
  loading: () => <p>Загрузка компонента...</p>,
});

SSR: включать или нет?

По умолчанию, компоненты через dynamic() будут загружаться и рендериться на сервере. Если вы хотите полностью исключить компонент из SSR, используйте:

const ClientOnlyComponent = dynamic(() => import('./ClientOnlyComponent'), {
  ssr: false,
});

Это полезно, если компонент зависит от window, document, или использует только клиентские библиотеки. На сервере браузера нет, так что window, document === null

Пример: лениво подгружаем модальное окно

Компонент EditUserModal.tsx

Это код самого окна:

interface EditUserModalProps {
  userId: string;
  onClose: () => void;
}

const EditUserModal: React.FC<EditUserModalProps> = ({ userId, onClose }) => (
  <div className="modal">
    <h2>Редактировать пользователя</h2>
    <p>ID: {userId}</p>
    <button onClick={onClose}>Закрыть</button>
  </div>
);

export default EditUserModal;

Использование с next/dynamic

Код компонента UsersPage в который мы вставляем наше лениво подгружаемое окно:

import dynamic from 'next/dynamic';
import { useState } from 'react';

const EditUserModal = dynamic(() => import('./EditUserModal'), {
  loading: () => <div>Загрузка...</div>,
  ssr: false,
});

export default function UsersPage() {
  const [selectedUserId, setSelectedUserId] = useState<string | null>(null);

  return (
    <div>
      <h1>Пользователи</h1>
      <button onClick={() => setSelectedUserId('1')}>Редактировать пользователя</button>

      {selectedUserId && (
        <EditUserModal
          userId={selectedUserId}
          onClose={() => setSelectedUserId(null)}
        />
      )}
    </div>
  );
}

Теперь модальное окно не будет загружено на сервере и будет подгружаться только при необходимости.

Дополнительно: динамическая загрузка именованных экспортов

Если компонент экспортируется не по умолчанию (не имеет export default):

// components/Charts.tsx
export const Chart = () => <div>График</div>;

Можно загрузить его так:

const Chart = dynamic(() =>
  import('./Charts').then(mod => mod.Chart)
);

Плюсы next/dynamic:

  • Работает с SSR.
  • Простая настройка загрузки.
  • Контроль над фолбэком.
  • Подходит для сложных и тяжёлых компонентов.

На что обратить внимание

Риск Решение
Компонент не виден при SSR Используйте ssr: false
Большой TypeScript-файл Разделяйте на меньшие части
Ошибки в типах Проверяйте экспорт компонента и пропсы
loading не отображается loading работает только с ssr: false

Типичные ошибки

  • React.lazy в SSR → будет ошибка, потому что import() не работает на сервере
  • Не указали ssr: false для клиентских компонентов → ReferenceError: window is not defined
  • dynamic() без fallback → пользователь может не понять, что компонент загружается

Если вы работаете с Next.js, особенно с SSR, то next/dynamicобязательный инструмент для оптимизации вашего приложения. Это более мощная и гибкая замена React.lazy, идеально встроенная в экосистему Next.js.

2
Задача
Модуль 3: React, 14 уровень, 7 лекция
Недоступна
Таблица пользователей — ленивый импорт по клику
Таблица пользователей — ленивый импорт по клику
Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ