Прямой ответ
Место формирования разметки определяет время до содержимого и распределение нагрузки, поэтому выбор подхода зависит от типа содержимого и трафика.
| Критерий | Рендеринг на клиенте | Рендеринг на сервере |
|---|---|---|
| Время до содержимого | После загрузки кода | После получения ответа |
| Нагрузка | На устройство пользователя | На сервер |
| Кэширование | Кэш ресурсов | Кэш готового HTML |
| Объём кода | Больше | Меньше |
| Персонализация | Без ограничения | Требует формирования при запросе |
CSR: ответ → загрузка кода → выполнение → содержимое
SSR: запрос → формирование HTML → содержимое
Содержимое при серверном рендеринге присутствует в первом ответе, поэтому ожидание загрузки и выполнения кода не требуется. О практике SSR — в статье про server-side rendering.
Время до содержимого и загрузка кода
Время до появления содержимого определяется местом формирования разметки, поэтому порядок этапов загрузки различается между подходами.
Формирование на клиенте. Ответ содержит пустую разметку, поэтому содержимое появляется после загрузки и выполнения кода, а время растёт с объёмом кода.
Формирование на сервере. Ответ содержит готовую разметку, поэтому содержимое отображается после получения ответа, а выполнение кода требуется только для интерактивности.
Влияние скорости соединения. На медленном соединении загрузка кода занимает больше времени, поэтому различие между подходами увеличивается.
Практическое следствие: страница, формируемая на клиенте, на медленном соединении показывает пустую область в течение времени загрузки кода, поэтому время до содержимого определяется сетью.
Отдельный аспект — объём клиентского кода. Серверный рендеринг переносит часть логики на сервер, поэтому объём загружаемого кода сокращается, и время до содержимого падает дополнительно.
Распределение нагрузки и кэширование
Нагрузка распределяется между устройством пользователя и сервером, поэтому выбор подхода определяет, какой ресурс становится ограничением.
Нагрузка на устройство. Формирование разметки выполняется на устройстве, поэтому сервер отдаёт статические ресурсы, а нагрузка на сервер минимальна.
Нагрузка на сервер. Формирование разметки выполняется для каждого запроса, поэтому время обработки запроса на сервере растёт с трафиком.
Кэширование результата. Готовый HTML кэшируется, поэтому число формирований сокращается, а нагрузка на сервер снижается.
Практическое следствие: серверный рендеринг без кэширования увеличивает нагрузку на сервер пропорционально трафику, поэтому при высоком трафике кэш становится обязательным.
Персонализация и статическая генерация
Возможность персонализации определяет применимость подхода, поэтому содержимое, зависящее от пользователя, требует формирования при запросе.
Персональное содержимое. Страница с содержимым, зависящим от пользователя, формируется при запросе либо на клиенте, поэтому статическая генерация не применима.
Одинаковое содержимое. Страница с одинаковым содержимым для всех пользователей генерируется при сборке, поэтому сервер отдаёт готовый файл.
Смешанный подход. Обезличенная часть формируется на сервере и кэшируется, персональная — на клиенте, поэтому нагрузка распределяется.
Практическое следствие: попытка кэшировать персональный ответ в общем кэше отдаёт содержимое одного пользователя другому, поэтому персонализация требует разделения кэша.
О статической генерации — в статье про SSG; о метриках — в статье про Core Web Vitals.
Сравнение по задачам
Выбор подхода определяется задачей страницы, поэтому разные типы страниц используют разное место формирования разметки.
Страница с содержимым для чтения. Формирование на сервере либо генерация при сборке сокращают время до содержимого, поэтому подход выбирается по частоте изменения данных.
Приложение с частыми действиями. Формирование на клиенте сокращает число обращений к серверу, поэтому отклик на действие выполняется без перезагрузки.
Страница с персональным содержимым. Формирование при запросе на сервере с кэшированием обезличенной части, поэтому нагрузка распределяется между кэшем и сервером.
Практическое следствие: единый подход для всех страниц сайта либо замедляет страницы с содержимым, либо увеличивает нагрузку на сервер без пользы.
Отдельный аспект — стоимость изменения. Переход между подходами затрагивает способ загрузки данных и формирования разметки, поэтому выбор фиксируется на этапе проектирования страницы, а не после выпуска.
Практика: выбор подхода к рендерингу
1. Определяйте тип содержимого страницы. Содержимое для чтения и приложение с действиями требуют разного места формирования.
2. Используйте серверное формирование для страниц с содержимым. Текст присутствует в первом ответе, поэтому время до содержимого сокращается.
3. Применяйте статическую генерацию для одинакового содержимого. Сервер отдаёт готовый файл без выполнения кода приложения.
4. Кэшируйте готовый HTML при высоком трафике. Число формирований сокращается, поэтому нагрузка на сервер снижается.
5. Не кэшируйте персональный ответ в общем кэше. Содержимое одного пользователя не отдаётся другому.
6. Формируйте персональную часть на клиенте. Обезличенная часть кэшируется, персональная загружается отдельно.
7. Измеряйте время до содержимого для каждого типа страниц. Влияние подхода подтверждается измерением.
Рекомендации:
- Не применяйте единый подход ко всем страницам сайта. Разные типы содержимого требуют разного места формирования разметки.
- Учитывайте нагрузку на сервер при выборе серверного рендеринга. Без кэширования нагрузка растёт пропорционально трафику.
- Сопоставляйте скорость соединения аудитории с подходом. На медленном соединении различие между подходами увеличивается.
- Фиксируйте выбор подхода на этапе проектирования страницы. Переход после выпуска затрагивает загрузку данных и формирование разметки.
- Пересматриваем подход при изменении типа содержимого. Страница, ставшая персональной, требует формирования при запросе.
Практический сценарий: страница блога загружалась медленнее приложения
Контекст: страница статьи открывалась дольше, чем экран приложения с частыми действиями, при этом объём данных статьи был небольшим.
- Диагностика. Измерение показало, что страница статьи формировала разметку на клиенте. Ответ содержал пустую разметку, поэтому текст появлялся после загрузки и выполнения кода, а время соответствовало объёму загружаемого кода.
- Причина. Единый подход к рендерингу применялся ко всем страницам сайта, поэтому страница с содержимым для чтения формировалась так же, как экран приложения.
- Действия. (а) Перенесли формирование разметки страницы статьи на сервер, чтобы текст присутствовал в первом ответе; (б) настроили кэширование готового HTML для статей, поскольку содержимое одинаково для всех пользователей; (в) сократили объём клиентского кода страницы статьи, оставив только необходимую интерактивность; (г) оставили формирование на клиенте для экранов приложения с частыми действиями, чтобы отклик не требовал обращения к серверу; (д) измерили время до содержимого для обоих типов страниц и зафиксировали сокращение для статьи.
- Результат. Страница статьи отображает текст после получения ответа, а экраны приложения сохраняют отклик без перезагрузки.
Вывод: единый подход к рендерингу для всех страниц замедляет страницы с содержимым для чтения, поскольку формирование выполняется на клиенте. Разделение подхода по типу содержимого с кэшированием готового HTML сокращает время до содержимого без потери отклика приложения.
FAQ
Чем клиентский рендеринг отличается от серверного? Местом формирования разметки. На клиенте содержимое появляется после загрузки кода, на сервере — после получения ответа.
Когда серверный рендеринг увеличивает нагрузку? При высоком трафике без кэширования готового HTML. Формирование разметки выполняется для каждого запроса.
Можно ли кэшировать персональную страницу? Нет, персональный ответ в общем кэше отдаёт содержимое одного пользователя другому. Кэшируется обезличенная часть.
Какой подход выбрать для страницы с содержимым для чтения? Серверное формирование либо статическую генерацию. Содержимое присутствует в первом ответе, поэтому время до отображения сокращается.
Источники: web.dev Rendering on the Web, RFC 9111 HTTP Caching, web.dev TBT — ссылки в шапке.