Два способа доставки фронтенда: статические файлы или работающий сервер

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

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

Статический фронтенд: файлы, которые говорят сами за себя

Представьте, что вы создаете страницу компании, сайт документации или маркетинговый лендинг. Вы пишете HTML, добавляете CSS, вставляете несколько изображений и загружаете это куда-нибудь. Браузер скачивает эти файлы и отображает их. Готово.

Это статический фронтенд. Все, что нужно браузеру, готово на этапе сборки. HTML, CSS, JavaScript, шрифты, изображения — все это становится файлами, которые могут лежать на простом веб-сервере, CDN или в S3-бакете. После развертывания не запускается ни один серверный процесс. Не нужно ждать запуска рантайма. Файлы просто лежат и ждут, когда их отдадут.

Но статический не значит простой. React- или Vue-приложение, которое получает данные из API, все равно можно собрать в статические файлы. Разница в том, что данные не появятся, пока браузер не выполнит JavaScript и не сделает запросы к API. Это называется клиентским рендерингом. Изначальный HTML может быть пустой оболочкой, а реальное содержимое подгружается уже после загрузки страницы.

Пайплайн для статического фронтенда прямолинеен:

  1. Запустить команду сборки.
  2. Собрать выходные файлы.
  3. Загрузить их в хранилище или на CDN.

Никакого перезапуска сервера. Никаких проверок здоровья. Никакого ожидания готовности процесса. Развертывание может быть таким же простым, как замена файлов в бакете или обновление указателя CDN. Если что-то пошло не так, вы откатываетесь к предыдущим файлам. Это быстро, дешево и сложно сломать.

SSR-фронтенд: страницы, приготовленные по запросу

Теперь рассмотрим интернет-магазин, который показывает цены в реальном времени, наличие на складе и персонализированные рекомендации. Если собрать это как статические файлы, пользователи увидят устаревшие данные, пока браузер не выполнит JavaScript и не получит свежую информацию. Эта задержка может стоить продаж, запутать клиентов и сделать приложение медлительным.

Здесь на помощь приходит серверный рендеринг (SSR). Когда пользователь запрашивает страницу, сервер получает актуальные данные, рендерит HTML и отправляет в браузер полностью сформированную страницу. Пользователь видит содержимое сразу, не дожидаясь загрузки и выполнения JavaScript.

SSR означает, что ваш фронтенд — это больше не просто файлы. Это работающее приложение, которому нужны сервер, зависимости, переменные окружения и правильная последовательность запуска. Пайплайн теперь больше похож на развертывание бэкенда:

  1. Собрать приложение в код, готовый к запуску на сервере.
  2. Установить зависимости рантайма.
  3. Настроить переменные окружения для целевой среды.
  4. Запустить серверный процесс или развернуть в контейнере.
  5. Выполнить проверки здоровья, чтобы убедиться, что сервер принимает запросы.
  6. Направить трафик на новую версию.
  7. Мониторить ошибки после переключения.

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

Компромисс: генерация статических сайтов

Существует гибридный подход — генерация статических сайтов (SSG). На этапе сборки он выглядит как SSR, но во время выполнения ведет себя как статический сайт. Рендеринг происходит один раз во время сборки, а не при каждом запросе. В результате получается набор предварительно отрендеренных HTML-файлов, которые можно отдавать статически.

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

Но у SSG есть компромисс. Если ваш контент часто меняется, вам придется пересобирать и переразвертывать весь сайт. Для блога с одним новым постом в неделю это нормально. Для интернет-магазина с обновлением остатков каждую минуту SSG становится непрактичным.

Что это значит для вашего пайплайна

Выбор между статикой, SSR и SSG — это не только вопрос архитектуры. Это вопрос того, как часто меняется ваш контент, как быстро пользователям нужно видеть обновления и сколько операционных накладных расходов может выдержать ваша команда.

Вот простой способ подумать об этом:

Диаграмма ниже проводит по процессу принятия решения и показывает соответствующий пайплайн для каждого пути.

flowchart TD A[Нужен ли приложению сервер?] -->|Нет| B[Статический фронтенд] A -->|Да| C[Контент меняется постоянно?] C -->|Нет| D[SSG - генерация статических сайтов] C -->|Да| E[SSR - серверный рендеринг] B --> F[Сборка статических файлов] F --> G[Загрузка на CDN / S3] G --> H[Отдача файлов] D --> I[Сборка и предварительный рендеринг HTML] I --> J[Загрузка статического вывода] J --> K[Отдача как статические файлы] E --> L[Сборка серверного кода] L --> M[Установка зависимостей рантайма] M --> N[Запуск серверного процесса] N --> O[Проверка здоровья и маршрутизация трафика]
  • Статика: Контент редко меняется. Пользователи могут пережить небольшую задержку перед появлением данных. Вы хотите максимально простое развертывание.
  • SSR: Контент меняется постоянно. Пользователям нужны свежие данные при каждой загрузке страницы. Вы готовы управлять серверным рантаймом.
  • SSG: Контент меняется периодически. Вы хотите быструю загрузку страниц без запуска сервера. Вы можете пересобрать сайт при обновлении контента.

Ваш пайплайн должен следовать этому решению, а не бороться с ним. Если вы выбрали статику, не добавляйте лишнего управления сервером. Если вы выбрали SSR, не делайте вид, что это просто папка с файлами.

Практический чек-лист перед принятием решения

Прежде чем выбрать стратегию развертывания, ответьте на эти вопросы:

  • Как часто меняется контент на этой странице? Каждую секунду, каждый час или каждую неделю?
  • Могут ли пользователи подождать, пока JavaScript получит данные после загрузки страницы, или им нужно содержимое немедленно?
  • Есть ли у вашей команды ресурсы для управления серверным рантаймом, включая мониторинг, перезапуски и откаты?
  • Как быстро вам нужно восстановиться после неудачного развертывания? Замена файлов быстрее, чем перезапуск сервера.
  • Будет ли одна и та же страница выглядеть по-разному для разных пользователей в зависимости от их сессии или местоположения?

Ваши ответы укажут на правильный подход. Не позволяйте фреймворку или хайпу решать за вас.

Конкретный вывод

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