Генерация статических сайтов (SSG) Обзор

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

Кроме того, благодаря архитектуре, лежащей в основе Qwik, производительность страницы также выигрывает, поскольку не требует шага "гидратации" Javascript, что может значительно снизить производительность и замедлить пользовательскую интерактивность. Благодаря предварительному рендерингу статических файлов index.html с помощью SSG и в сочетании с возобновляемостью, генерация статических сайтов обеспечивает множество преимуществ в производительности по сравнению с традиционными решениями.

SSG vs. Рендеринг на стороне сервера (SSR)

Qwik City способен принять приложение Qwik, независимо от его типа, будь это "webapp" или "website", и генерировать статический HTML. После генерации HTML-файлов Qwik будет пропускать перестройку приложения, используя возобновляемость, поскольку приложение уже сгенерировано как HTML. И генерация статических сайтов (SSG), и рендеринг на стороне сервера (SSR) используют один и тот же процесс для генерации HTML. Однако главное различие между SSG и SSR - это "когда" генерируется HTML.

При традиционной настройке SSG предварительно рендерит каждую веб-страницу во время сборки, в то время как SSR рендерит каждую веб-страницу по требованию для каждого HTTP-запроса. SSG нужно генерировать HTML только один раз за сборку, что отлично подходит для веб-страниц, где несколько посетителей должны видеть один и тот же контент. Напротив, SSR отлично подходит, когда веб-страница может отличаться для каждого пользователя, и потребуется отображать пользовательский HTML для каждого отдельного HTTP-запроса.

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

Однако, например, страница учётной записи обычно будет содержать разное содержимое для каждого вошедшего в систему пользователя. В такой конфигурации каждый пользователь должен получать свой собственный HTML-код с информацией о своей учётной записи, вместо того, чтобы все видели один и тот же контент. Именно здесь SSR был бы предпочтительнее.

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

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

Настройка генерации статических сайтов

Генерация статического сайта делается встроенным адаптером, для запуска которого наберите:

npm run qwik add static

Выберите Adapter: Static site (.html files). Готово!

Изменения

Выполнение приведённой выше команды внесёт следующие изменения в ваш проект:

  • Скрипт build.server будет автоматически добавлен в ваш файл package.json.
  • Будет создан файл adapters/static/vite.config.ts.

Файлы сборки будут сгенерированы в папке dist.

Вы можете создать свой статический сайт, используя:

npm run build.server

Настройка SSG

Файл adapters/static/vite.config.ts также включает конфигурацию SSG, которая будет индивидуальной для каждой реализации.

origin

URL origin представляет собой комбинацию схемы (протокола) и имени хоста (домена). Например, https://qwik.builder.io имеет протокол https:// и домен qwik.builder.io. Однако origin не включает в себя pathname (маршрут).

Параметр origin используется для предоставления полного URL-адреса во время генерации статических сайтов (SSG), а также для того, чтобы формировать полный URL-адрес, а не просто pathname. Например, для создания правильного канонического тега URL или URL-адреса в файле sitemap.xml, должен быть указан и origin.

Если сайт также начинается с имени, отличного от /, используйте опцию base в конфигурации Vite (опция basePathname в конфигурации Qwik City устарела).

outDir

outDir - это каталог файловой системы, куда должны быть записаны статические файлы. В приведенном выше примере используется метод среды Node.js fileURLToPath. Он формирует название абсолютного пути в файловой системе для записи статических HTML-файлов.

Среды выполнения Javascript

Для Javascript-проекта довольно часто выполнение сборки работает поверх Node.js. Однако ядро генерации статического сайта Qwik City не привязано к использованию только Node.js, именно поэтому функция qwikCityGenerate() импортируется из пакета @builder.io/qwik-city/static/node. Это дает Qwik City гибкость для того, чтобы в будущем также генерировать SSG и из других сред выполнения, таких как Deno или Bun. Изменится лишь пакет импорта.

Динамические маршруты SSG

До сих пор мы обсуждали генерацию статических HTML-файлов только для одного маршрута. Однако в большинстве случаев вы захотите генерировать HTML-файлы для нескольких маршрутов с динамическими параметрами. Например, сайт может иметь отдельный путь маршрута для каждого продукта, такой как /product/:id. В этом случае вы захотите генерировать HTML-файлы для каждой страницы продукта, что потребует создания HTML-файлов для каждого идентификатора продукта.

import { component$ } from '@builder.io/qwik';
import { useLocation, type StaticGenerateHandler } from '@builder.io/qwik-city';
import { loadProductIds } from './load-product-ids';
 
export default component$(() => {
  const { params } = useLocation();
 
  return <p>Пример: {params.id}</p>;
});
 
export const onStaticGenerate: StaticGenerateHandler = async ({ env }) => {
  // Пример загрузки параметров для данного варианта использования,
  // каждая реализация будет разной.
  const ids = await loadProductIds({
    apiKey: env.get('API_KEY'),
  });
 
  return {
    params: ids.map((id) => {
      return { id };
    }),
  };
};

В приведённом выше примере функция onStaticGenerate() загружает идентификаторы товаров из функции loadProductIds() путем запроса к API с ключом API, полученным из переменной окружения. Эта функция будет индивидуальной для каждой реализации, но общая идея заключается в том, что вам нужно будет загрузить данные для каждого ID продукта, а затем сгенерировать HTML файлы для каждого продукта.

Функция onStaticGenerate должна экспортироваться с верхнего уровня модуля и возвращать объект со свойством params. Свойство params должно представлять собой массив объектов, где каждый объект является набором параметров для маршрута. Например, если путь маршрута - /product/:id, то массив params должен представлять собой массив объектов со свойством id.

Структура каталогов для этого примера будет следующей:

src/
└── routes/
    └── product/
        └── [id]/
            └── index.tsx

Обратите внимание, что файл index.tsx находится в директории с именем [id]. Это специальное имя каталога, которое указывает Qwik City генерировать HTML-файлы для каждого параметра id. Файл index.tsx - это файл по умолчанию, который Qwik City будет использовать при генерации HTML-файлов для пути маршрута.

Участники

Спасибо всем участникам, которые помогли сделать эту документацию лучше!

  • adamdbradley
  • AnthonyPAlicea
  • mhevery
  • ibousfiha
  • Kocal
  • eric-burel
  • julianobrasil
  • mrhoodz
  • hamatoyogi