Server-Side Rendering (SSR) представляет собой подход, при котором HTML-страница формируется на сервере, а не в браузере клиента. В контексте Vue.js это означает, что Vue-компоненты рендерятся на сервере, и готовый HTML отправляется пользователю, что повышает скорость первичной загрузки и улучшает SEO.
Предварительный рендеринг на сервере В отличие от классического клиентского рендеринга, где весь процесс рендеринга происходит в браузере, SSR формирует полноценный HTML на сервере. Когда браузер получает страницу, она уже содержит готовую разметку, а Vue на клиенте «гидратирует» её, превращая статический HTML в интерактивный интерфейс.
Гидратация (Hydration) Гидратация — это процесс, при котором Vue на клиенте связывает уже существующий серверный HTML с виртуальным DOM. В результате динамические возможности Vue (реактивность, события) становятся доступными, но при этом пользователь сразу видит содержимое страницы, не дожидаясь загрузки JavaScript.
Разделение клиентского и серверного кода Для SSR
необходимо различать код, который может выполняться на сервере, и код,
требующий доступа к браузерным API (например, window или
document). Использование универсальных (isomorphic)
компонентов позволяет безопасно рендерить их как на сервере, так и на
клиенте.
Vue предоставляет отдельный пакет @vue/server-renderer
для серверного рендеринга и фреймворк Nuxt.js для упрощения
SSR-приложений. Основные этапы настройки:
Создание универсального Vue-приложения Универсальное приложение должно экспортировать функцию, возвращающую новый экземпляр Vue, чтобы каждый запрос создавал отдельный рендеринг:
import { createSSRApp } from 'vue'
import App from './App.vue'
export function createApp() {
const app = createSSRApp(App)
return { app }
}Рендеринг на сервере Серверный рендеринг
выполняется с помощью renderToString, который возвращает
готовый HTML:
import { renderToString } from '@vue/server-renderer'
import { createApp } from './app'
const { app } = createApp()
renderToString(app).then(html => {
console.log(html) // готовый HTML для отправки клиенту
})Гидратация на клиенте На клиенте Vue
«подхватывает» серверный HTML с помощью createApp и
mount:
import { createApp } from './app'
const { app } = createApp()
app.mount('#app') // элемент с уже существующей серверной разметкойОдной из ключевых задач SSR является загрузка данных до рендеринга.
Для этого используется асинхронная функция asyncData или
подход с предварительной загрузкой данных в setup или в
Vuex.
Пример с использованием Vuex:
// store.js
export const store = {
state: () => ({ items: [] }),
actions: {
async fetchItems({ commit }) {
const response = await fetch('https://api.example.com/items')
const data = await response.json()
commit('setItems', data)
}
},
mutations: {
setItems(state, items) {
state.items = items
}
}
}
// server.js
import { store } from './store'
await store.dispatch('fetchItems')
Загрузка данных на сервере позволяет отдать пользователю полностью сформированную страницу с уже доступной информацией.
Преимущества:
Ограничения:
Для SSR важно учитывать, что браузерный JavaScript может выполнять
динамическое обновление DOM только после гидратации. Поэтому любые
операции, зависящие от window или пользовательских событий,
следует выполнять только на клиенте:
if (typeof window !== 'undefined') {
// код, доступный только в браузере
}
SSR обычно сочетается с Vue Router в режиме history. Для
каждого запроса на сервере создаётся новый экземпляр маршрутизатора:
import { createRouter, createMemoryHistory } from 'vue-router'
import routes from './routes'
export function createApp() {
const app = createSSRApp(App)
const router = createRouter({
history: createMemoryHistory(),
routes
})
app.use(router)
return { app, router }
}
После этого сервер может рендерить нужный маршрут на основе URL-запроса.
Nuxt.js автоматизирует большинство задач SSR: конфигурацию сервера,
маршрутизацию, гидратацию, управление данными. В Nuxt можно
сосредоточиться на компонентах и страницах, а SSR будет обеспечиваться
«из коробки». Nuxt поддерживает asyncData,
fetch, модули Vuex и динамические маршруты, что упрощает
создание SEO-оптимизированных приложений.
Кэширование HTML Для часто посещаемых страниц можно кэшировать готовый HTML, чтобы снизить нагрузку на сервер.
Ленивая загрузка компонентов Использование
динамического импорта (defineAsyncComponent) позволяет
разделять код и загружать только необходимые компоненты.
Минификация и сжатие Сервер должен отдавать минифицированный HTML и включать gzip или brotli-сжатие для ускорения передачи данных.
Контроль ресурсов SSR увеличивает использование CPU на сервере, поэтому необходимо балансировать между рендерингом на сервере и клиенте.
Server-Side Rendering в Vue.js объединяет преимущества быстрого отображения контента и полной функциональности Vue, обеспечивая высокую производительность и SEO-оптимизацию. Использование SSR требует внимания к архитектуре приложения, работе с данными и маршрутизацией, но позволяет создавать профессиональные масштабируемые приложения с богатым пользовательским интерфейсом.