Прямой ответ
Рендеринг на сервере формирует готовый HTML до отправки ответа, поэтому содержимое отображается до загрузки и выполнения клиентского кода.
| Параметр | Что определяет |
|---|---|
| Формирование HTML | Сборка разметки на сервере |
| Передача данных | Значения, подставляемые в шаблон |
| Кэш ответа | Повторное использование готового HTML |
| Время до содержимого | Момент появления текста на экране |
def render_page(request):
data = load_product(request.path)
html = template.render(title=data.title, price=data.price)
return Response(html, headers={"Cache-Control": "public, max-age=60"})
Разметка с содержимым отправляется в первом ответе, поэтому текст виден до выполнения клиентского кода. О гидратации — в статье про гидратацию страницы.
Формирование HTML и передача данных
Разметка собирается на сервере из шаблона и данных, поэтому содержимое присутствует в первом ответе сервера.
Шаблон страницы. Разметка с местами для значений подставляется данными, поэтому структура страницы формируется до отправки.
Данные для подстановки. Значения загружаются на сервере, поэтому запрос к источнику выполняется до отправки ответа.
Готовая разметка. Ответ содержит текст и структуру, поэтому отображение не ждёт загрузки и выполнения клиентского кода.
Практическое следствие: страница, формируемая на клиенте, отправляет пустую разметку, поэтому содержимое появляется только после загрузки и выполнения кода.
Отдельный аспект — нагрузка на сервер. Формирование разметки выполняется для каждого запроса, поэтому время обработки запроса на сервере растёт по сравнению с отдачей готового файла.
Кэширование ответа и нагрузка
Кэширование готового HTML сокращает число формирований разметки, поэтому нагрузка на сервер снижается при повторяющихся запросах.
Срок хранения ответа. Заголовок кэша задаёт период, в течение которого ответ повторно используется, поэтому формирование не выполняется повторно.
Различие содержимого. Ответ, зависящий от пользователя, кэшируется отдельно либо не кэшируется, поэтому персональное содержимое не попадает в общий кэш.
Инвалидация кэша. Изменение данных требует обновления кэша, поэтому срок хранения выбирается по допустимой задержке обновления.
Практическое следствие: персональный ответ, помещённый в общий кэш, отдаёт содержимое одного пользователя другому, поэтому кэширование применяется только к обезличенной части.
Влияние на метрики загрузки
Рендеринг на сервере сокращает время до появления содержимого, поэтому метрики загрузки улучшаются по сравнению с формированием на клиенте.
Время до содержимого. Текст отображается после получения ответа, поэтому ожидание выполнения клиентского кода не требуется.
Объём клиентского кода. Часть логики выполняется на сервере, поэтому объём загружаемого кода сокращается.
Доступность содержимого. Разметка присутствует в ответе, поэтому содержимое читается без выполнения кода.
Практическое следствие: страница, формируемая на клиенте, показывает пустую разметку до выполнения кода, поэтому время до содержимого растёт с объёмом загружаемого кода.
О выборе подхода — в статье про рендеринг: клиент против сервера; о метриках — в статье про Core Web Vitals.
Практика: настройка рендеринга на сервере
1. Формируйте разметку на сервере для страниц с содержимым. Текст присутствует в первом ответе, поэтому отображение не ждёт клиентского кода.
2. Загружайте данные до формирования разметки. Значения подставляются в шаблон, поэтому запрос к источнику выполняется на сервере.
3. Кэшируйте готовый HTML для обезличенного содержимого. Число формирований разметки сокращается, поэтому нагрузка на сервер снижается.
4. Не кэшируйте персональный ответ в общем кэше. Содержимое одного пользователя не отдаётся другому.
5. Выбирайте срок хранения кэша по допустимой задержке обновления. Изменение данных отражается в пределах установленного периода.
6. Сокращайте объём клиентского кода для серверных страниц. Часть логики выполнена на сервере, поэтому загрузка кода не требуется.
7. Измеряйте время до содержимого. Улучшение метрики подтверждается измерением, а не предположением.
Рекомендации:
- Не применяйте рендеринг на сервере к страницам без содержимого. Формирование разметки добавляет нагрузку без пользы для отображения.
- Учитывайте нагрузку на сервер при высоком трафике. Формирование разметки выполняется для каждого запроса без кэша.
- Сопоставляйте срок кэша с частотой изменения данных. Длительный срок хранения отдаёт прежнее содержимое после обновления.
- Фиксируйте измерение метрик до и после изменения. Влияние на загрузку подтверждается измерением.
- Пересматриваем набор серверных страниц при изменении структуры сайта. Новая страница с содержимым требует серверного формирования.
Практический сценарий: страница показывала пустую разметку до загрузки кода
Контекст: страница товара отображала пустую область несколько секунд на медленном соединении, при этом данные запрашивались быстро.
- Диагностика. Проверка показала, что ответ сервера содержал пустую разметку, а содержимое формировалось после загрузки и выполнения клиентского кода. Время до появления текста соответствовало времени загрузки кода, а не времени запроса данных.
- Причина. Разметка формировалась на клиенте, поэтому первый ответ не содержал содержимого, и отображение зависело от объёма загружаемого кода.
- Действия. (а) Перенесли формирование разметки на сервер, чтобы текст присутствовал в первом ответе; (б) загрузили данные на сервере до подстановки в шаблон, чтобы запрос к источнику не выполнялся на клиенте; (в) настроили кэширование готового HTML для обезличенной части страницы, чтобы нагрузка на сервер не росла; (г) сократили объём клиентского кода, поскольку часть логики выполнялась на сервере; (д) измерили время до содержимого до и после изменения и зафиксировали сокращение.
- Результат. Содержимое отображается после получения ответа, поэтому время до появления текста не зависит от объёма клиентского кода.
Вывод: формирование разметки на клиенте отправляет пустой ответ, поэтому отображение содержимого ждёт загрузки и выполнения кода. Рендеринг на сервере с кэшированием готового HTML сокращает время до содержимого и снижает объём загружаемого кода.
FAQ
Что даёт рендеринг страницы на сервере? Содержимое присутствует в первом ответе, поэтому текст отображается до загрузки и выполнения клиентского кода.
Почему растёт нагрузка на сервер при SSR? Формирование разметки выполняется для каждого запроса. Кэширование готового HTML сокращает число формирований.
Можно ли кэшировать персональную страницу? Нет, персональный ответ в общем кэше отдаёт содержимое одного пользователя другому. Кэшируется только обезличенная часть.
Как SSR влияет на объём клиентского кода? Часть логики выполняется на сервере, поэтому объём загружаемого кода сокращается и загрузка ускоряется.
Источники: web.dev Rendering on the Web, HTML DOM, RFC 9110 HTTP Semantics — ссылки в шапке.