Svelte
SSR, CSR и prerender
Блог-пост, корзина магазина и внутренняя админка - три разные страницы с разными требованиями. Пост одинаков для всех и должен мгновенно открываться у поисковика, его разумно собрать в статический HTML заранее. Корзина зависит от пользователя и должна рендериться на сервере на каждый запрос. Админка живёт за логином, индексировать её незачем, и она может быть чисто клиентским приложением. SvelteKit покрывает все три случая тремя режимами рендеринга, и переключаются они парой опций в файле страницы, без смены фреймворка.
- Блог и документация: пререндер в статический HTML на сборке, мгновенная отдача с CDN и полная индексация
- Главная и каталог магазина: SSR на каждый запрос, поисковик видит товары, цены подставляются актуальные
- Личный кабинет за логином: можно отключить SSR и отдать как клиентское приложение, индексация не нужна
- Лендинг с маркетинговым контентом: пререндер ради скорости и SEO без серверной нагрузки
- Дашборд с живыми графиками: первый HTML с сервера, дальше обновления данных на клиенте
Предварительные знания
- Файловый роутинг SvelteKit и роль +page.svelte
- Различие сервера и браузера как сред исполнения JavaScript
- Базовое понимание SEO: поисковику нужен готовый HTML, а не пустая страница
Серверный и клиентский рендеринг
Рендеринг - это превращение компонентов в HTML, который видит пользователь. При серверном рендеринге (SSR) HTML собирается на сервере и приходит в браузер уже готовым: пользователь и поисковик сразу видят содержимое. При клиентском рендеринге (CSR) сервер отдаёт почти пустую страницу с подключённым JavaScript, а разметку строит уже браузер после загрузки и выполнения скриптов.
| Свойство | SSR | CSR |
|---|---|---|
| Где строится HTML | На сервере при запросе | В браузере после загрузки JS |
| Первый экран | Виден сразу с содержимым | Пусто, пока не выполнится JS |
| SEO | Поисковик видит готовый HTML | Зависит от исполнения JS краулером |
| Нагрузка | Работа на сервере на каждый запрос | Работа перенесена на устройство клиента |
У каждого подхода своя цена. SSR даёт быстрый осмысленный первый экран и надёжную индексацию, но нагружает сервер вычислением HTML на каждый запрос. CSR разгружает сервер и хорош для приложений за логином, где SEO не нужно, но пользователь сперва видит пустоту, пока грузится и исполняется JavaScript. Выбор зависит от того, важны ли индексация и скорость первого экрана.
SSR в SvelteKit не означает отказ от интерактивности. Сервер отдаёт готовый HTML, а затем тот же код запускается в браузере и делает страницу живой - это гидрация. Так совмещаются быстрый первый экран от SSR и интерактивность клиентского приложения.
Чем серверный рендеринг (SSR) отличается от клиентского (CSR) с точки зрения первого экрана?
Что SvelteKit делает по умолчанию
SvelteKit по умолчанию сочетает оба подхода. На первый запрос страницы он делает SSR: сервер отдаёт готовый HTML, чтобы первый экран и SEO работали сразу. Затем в браузере приложение гидрируется и берёт навигацию на себя - переходы между страницами происходят на клиенте без полной перезагрузки, как в одностраничном приложении. Это сочетание даёт и быстрый первый экран, и плавную дальнейшую навигацию.
Такой гибрид часто называют универсальным или изоморфным рендерингом: один и тот же код страницы исполняется и на сервере для первого HTML, и в браузере для интерактивности и навигации. Разработчику не нужно выбирать между сайтом и приложением - по умолчанию страница ведёт себя как и то, и другое.
Поведение по умолчанию подходит большинству страниц, и менять его стоит лишь осознанно. Переключают режим тогда, когда у конкретной страницы особые требования: чисто статический контент под пререндер или приватная админка без нужды в SSR.
Как SvelteKit рендерит страницу по умолчанию?
Переключение режима: ssr, csr, prerender
Режим рендеринга задаётся экспортом опций из +page.js (или +page.server.js, или +layout.js для целого раздела). Три булевы опции управляют поведением: ssr включает или отключает серверный рендеринг, csr - клиентский JavaScript и гидрацию, prerender - генерацию статического HTML на сборке. По умолчанию ssr и csr равны true, prerender - false.
prerender = true говорит SvelteKit построить HTML страницы один раз на этапе сборки. Это работает только для контента, одинакового для всех пользователей и не зависящего от запроса: блог, документация, лендинг. Страница с данными конкретного пользователя пререндерить нельзя - на сборке этих данных ещё нет. ssr = false превращает страницу в чистое клиентское приложение, что уместно за логином, где индексация не нужна.
Отключение и ssr, и csr вместе (оба false) оставит страницу пустой: ни сервер не построит HTML, ни браузер. Такая комбинация осмысленна только в паре с prerender = true, когда HTML уже готов на сборке и интерактивность не нужна. Без пререндера это ошибка конфигурации.
Статью блога нужно отдавать максимально быстро как статический HTML, одинаковый для всех. Какую опцию задать на странице?
Связь с другими темами
Этот урок задаёт режимы рендеринга, на которые опираются следующие темы модуля:
- Гидрация — Как серверный HTML оживает в браузере и почему точечная гидрация Svelte быстрее
- Адаптеры и пререндеринг — Конкретная платформа деплоя реализует выбранный режим через свой адаптер
- Load-функции — Режим рендера определяет, где и когда исполняется load для страницы
Итог
- SSR рендерит HTML на сервере на каждый запрос - хорош для SEO и динамического, зависящего от пользователя контента
- CSR (без SSR) отдаёт пустую оболочку и строит разметку в браузере - годится для приватных приложений за логином
- Prerender генерирует статический HTML один раз на этапе сборки - максимально быстрая отдача для неизменного контента
- По умолчанию SvelteKit делает SSR при первом запросе плюс CSR-навигацию между страницами без перезагрузки
- Режим переключают опциями в +page.js или +page.server.js: export const ssr, csr, prerender со значением true или false
Связанные уроки
- sv-26-hydration — После SSR страница в браузере оживает гидрацией; следующий урок разбирает, как это делает Svelte и почему быстро
- sv-27-prerendering-adapters — Пререндеринг и режим рендера реализуются конкретным адаптером под платформу деплоя
- sv-19-load-functions — Режим рендера определяет, где исполняется load: на сервере при каждом запросе, в браузере или единожды на сборке