Рендеринг

Рендеринг преобразует написанный вами код в пользовательские интерфейсы. React и Next.js позволяют создавать гибридные веб-приложения, где части кода могут рендериться на сервере или клиенте. Этот раздел поможет понять различия между этими средами рендеринга, стратегиями и средами выполнения.

Основы

Для начала полезно ознакомиться с тремя фундаментальными концепциями веба:

Среды рендеринга

Существует две среды, в которых могут рендериться веб-приложения: клиент и сервер.

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

Исторически разработчикам приходилось использовать разные языки (например, JavaScript, PHP) и фреймворки для написания серверного и клиентского кода. С React разработчики могут использовать один язык (JavaScript) и один фреймворк (например, Next.js или другой на выбор). Эта гибкость позволяет писать код для обеих сред без переключения контекста.

Однако каждая среда имеет свои возможности и ограничения. Поэтому код для сервера и клиента не всегда одинаков. Некоторые операции (например, получение данных или управление состоянием пользователя) лучше подходят для одной среды, чем для другой.

Понимание этих различий ключевое для эффективного использования React и Next.js. Подробнее о различиях и случаях использования мы расскажем на страницах Серверных и Клиентских компонентов, а пока продолжим строить нашу основу.

Жизненный цикл запроса-ответа

В целом все веб-сайты следуют одному жизненному циклу запроса-ответа:

  1. Действие пользователя: Пользователь взаимодействует с веб-приложением. Это может быть клик по ссылке, отправка формы или ввод URL в адресную строку браузера.
  2. HTTP-запрос: Клиент отправляет HTTP-запрос на сервер, содержащий информацию о запрашиваемых ресурсах, используемом методе (например, GET, POST) и дополнительные данные при необходимости.
  3. Сервер: Сервер обрабатывает запрос и отвечает соответствующими ресурсами. Этот процесс может включать несколько шагов, таких как маршрутизация, получение данных и т.д.
  4. HTTP-ответ: После обработки запроса сервер отправляет HTTP-ответ клиенту. Ответ содержит код состояния (указывающий на успешность запроса) и запрошенные ресурсы (например, HTML, CSS, JavaScript, статические файлы и т.д.).
  5. Клиент: Клиент обрабатывает ресурсы для рендеринга пользовательского интерфейса.
  6. Действие пользователя: После рендеринга интерфейса пользователь может взаимодействовать с ним, и цикл начинается заново.

Важная часть создания гибридного веб-приложения — решение о том, как разделить работу в этом цикле и где разместить сетевую границу.

Сетевая граница

В веб-разработке сетевая граница — это концептуальная линия, разделяющая разные среды. Например, клиент и сервер или сервер и хранилище данных.

В React вы можете выбрать, где разместить клиент-серверную границу, где это наиболее логично.

За кулисами работа разделяется на две части: граф клиентских модулей и граф серверных модулей. Граф серверных модулей содержит все компоненты, рендерящиеся на сервере, а граф клиентских модулей — все компоненты, рендерящиеся на клиенте.

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

Вы можете использовать директиву React "use client" для определения границы. Также есть директива "use server", которая указывает React выполнять некоторые вычисления на сервере при работе на клиенте.

Создание гибридных приложений

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

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

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

Эта концепция станет понятнее, когда мы рассмотрим, как можно перемежать клиентские и серверные компоненты в одном дереве компонентов.