Статическая генерация (SSG)

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


Основные концепции SSG

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

  2. Данные во время сборки Данные могут быть получены из API или локальных источников до генерации страницы. Это означает, что конечный HTML уже содержит весь необходимый контент, без дополнительной загрузки данных на клиенте.

  3. Сравнение с SSR и CSR

    • CSR (Client-Side Rendering): страница загружается пустой HTML с JavaScript, который динамически отрисовывает контент.
    • SSR (Server-Side Rendering): сервер формирует HTML на каждый запрос.
    • SSG (Static Site Generation): HTML формируется один раз на этапе сборки и раздается как готовый файл.

Интеграция SSG в Vue.js

Наиболее популярным инструментом для статической генерации во Vue.js является Nuxt.js. Nuxt поддерживает режим target: 'static', который позволяет строить приложение как полностью статический сайт.

Пример конфигурации Nuxt для SSG:
export default {
  target: 'static',
  generate: {
    fallback: true, // Для маршрутов, не сгенерированных заранее
    routes: [
      '/about',
      '/contact'
    ]
  }
}
  • target: 'static' указывает на необходимость генерации статических файлов.
  • fallback: true создает 404.html для маршрутов, не сгенерированных заранее.
  • routes позволяет явно определить, какие маршруты предгенерировать.

Генерация страниц с динамическими данными

Динамические страницы могут быть сгенерированы, если заранее известны все возможные параметры. Например, при работе с блогом:

export default {
  async generate() {
    const posts = await fetch('https://api.example.com/posts').then(res => res.json());
    return posts.map(post => `/blog/${post.id}`);
  }
}

В этом примере API возвращает список постов, и на его основе Nuxt создает статические HTML-страницы для каждого поста.


Компоненты и маршруты

Все стандартные Vue-компоненты полностью поддерживаются в режиме SSG. Важно помнить:

  • Асинхронные компоненты должны быть корректно обработаны во время сборки.
  • Компоненты с клиентским состоянием (например, интерактивные виджеты) могут требовать гидратации на клиенте. Гидратация обеспечивает взаимодействие с DOM после загрузки статического HTML.

Гидратация

Гидратация — процесс привязки Vue-компонентов к уже существующему HTML, сгенерированному на этапе сборки. Это позволяет:

  • Сохранять интерактивность компонентов после загрузки страницы.
  • Снижать время рендеринга, поскольку большая часть разметки уже создана.

Пример использования гидратации:



HTML будет содержать начальное состояние счетчика, а Vue на клиенте продолжит его работу динамически.


Ограничения SSG

  • Не подходит для часто меняющегося контента, который должен обновляться в реальном времени.
  • Не все маршруты могут быть предгенерированы, особенно если количество параметров велико. В таких случаях используются fallback-страницы или комбинация SSG и CSR.
  • Большой объем данных может увеличить время сборки.

Оптимизация сборки

  1. Разделение маршрутов на чанки Использование асинхронных импортов для компонентов и страниц ускоряет время загрузки.

  2. Кэширование данных Предзагрузка и кэширование внешних API-данных снижает нагрузку на сборку.

  3. Lazy Loading изображений и компонентов Даже в статическом сайте важно минимизировать начальный объем загружаемых ресурсов.


Применение SSG в современных проектах

  • Блоги и новостные сайты
  • Документация и справочные порталы
  • Лэндинги и маркетинговые сайты
  • Каталоги продуктов с ограниченным числом товаров

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