Статический и динамический рендеринг

В предыдущей главе вы получали данные для страницы обзора дашборда. Однако мы кратко обсудили два ограничения текущей настройки:

  1. Запросы данных создают непреднамеренный водопад (waterfall).
  2. Дашборд статичен, поэтому любые обновления данных не будут отражены в вашем приложении.

Что такое статический рендеринг?

При статическом рендеринге получение данных и рендеринг происходят на сервере во время сборки (при деплое) или при ревалидации данных.

Когда пользователь посещает ваше приложение, отдается закешированный результат. У статического рендеринга есть несколько преимуществ:

  • Быстрые сайты - Предварительно отрендеренный контент может быть закеширован и глобально распределен при деплое на платформы вроде Vercel. Это гарантирует, что пользователи по всему миру смогут получать доступ к контенту вашего сайта быстрее и надежнее.
  • Сниженная нагрузка на сервер - Поскольку контент кешируется, ваш сервер не должен динамически генерировать контент для каждого запроса пользователя. Это может снизить вычислительные затраты.
  • SEO - Предварительно отрендеренный контент легче индексируется поисковыми роботами, так как контент уже доступен при загрузке страницы. Это может улучшить позиции в поисковой выдаче.

Статический рендеринг полезен для интерфейсов без данных или с данными, общими для всех пользователей, например, статических блогов или страниц товаров. Он может не подходить для дашборда с персонализированными данными, которые часто обновляются.

Противоположность статического рендеринга — динамический рендеринг.

Что такое динамический рендеринг?

При динамическом рендеринге контент генерируется на сервере для каждого пользователя в момент запроса (когда пользователь посещает страницу). У динамического рендеринга есть несколько преимуществ:

  • Данные в реальном времени - Динамический рендеринг позволяет вашему приложению отображать данные в реальном времени или часто обновляемые данные. Это идеально для приложений, где данные часто меняются.
  • Персонализированный контент - Легче отдавать персонализированный контент, например, дашборды или профили пользователей, и обновлять данные на основе взаимодействия с пользователем.
  • Информация в момент запроса - Динамический рендеринг позволяет получать информацию, которая известна только в момент запроса, например, куки или параметры URL.

Имитация медленного получения данных

Приложение-дашборд, которое мы создаем, является динамическим.

Однако остается одна проблема, упомянутая в предыдущей главе. Что произойдет, если один запрос данных будет медленнее остальных?

Давайте имитируем медленное получение данных. В файле app/lib/data.ts раскомментируйте console.log и setTimeout внутри функции fetchRevenue():

/app/lib/data.ts
export async function fetchRevenue() {
  try {
    // Искусственно задерживаем ответ для демонстрации.
    // Не делайте так в продакшене :)
    console.log('Получение данных о выручке...');
    await new Promise((resolve) => setTimeout(resolve, 3000));
 
    const data = await sql<Revenue[]>`SELECT * FROM revenue`;
 
    console.log('Данные получены через 3 секунды.');
 
    return data;
  } catch (error) {
    console.error('Ошибка базы данных:', error);
    throw new Error('Не удалось получить данные о выручке.');
  }
}

Теперь откройте http://localhost:3000/dashboard/ в новой вкладке и обратите внимание, что страница загружается дольше. В терминале вы также должны увидеть следующие сообщения:

Получение данных о выручке...
Данные получены через 3 секунды.

Здесь мы добавили искусственную задержку в 3 секунды, чтобы имитировать медленное получение данных. В результате вся страница блокируется от показа пользователю, пока данные не будут получены. Это подводит нас к общей проблеме, которую приходится решать разработчикам:

При динамическом рендеринге скорость вашего приложения определяется самым медленным запросом данных.