Оптимизация для SSR

Element Plus предоставляет полный набор компонентов для Vue 3, которые могут быть интегрированы с серверным рендерингом (SSR). Основная цель оптимизации для SSR — обеспечить корректное отображение компонентов на сервере без ошибок гидратации на клиенте. Важно учитывать, что не все компоненты полностью поддерживают SSR «из коробки», особенно те, которые зависят от window, document или сторонних браузерных API.

Ключевые моменты:

  • Компоненты должны быть изолированы от браузерных зависимостей при рендеринге на сервере.
  • Lazy hydration помогает уменьшить нагрузку на клиент, рендеря тяжелые компоненты только после инициализации.
  • Для динамических и интерактивных элементов необходимо использовать директивы или условный рендеринг с проверкой платформы.

Настройка SSR в проекте на Vue 3 с Element Plus

Для интеграции Element Plus в SSR-проект создается серверная сборка с использованием Vite или Webpack:

  1. Установка зависимостей:
npm install element-plus vue@3 vue-server-renderer
  1. Создание серверного рендера:
  • Создается server.js или аналогичный файл с функцией renderToString из @vue/server-renderer.
  • Внутри app необходимо регистрировать все глобальные компоненты Element Plus:
import { createSSRApp } from 'vue';
import ElementPlus from 'element-plus';
import App from './App.vue';

export function createApp() {
  const app = createSSRApp(App);
  app.use(ElementPlus);
  return { app };
}
  1. Управление стилями: Element Plus использует CSS variables и SCSS-переменные. Для SSR важно собрать CSS на сервере и передать его клиенту, чтобы избежать Flicker of Unstyled Content (FOUC).

Оптимизация загрузки компонентов

Lazy Loading и Tree Shaking

Element Plus поддерживает поименный импорт компонентов, что уменьшает размер бандла:

import { ElButton, ElInput } from 'element-plus';

Для SSR это критично: ненужные компоненты не рендерятся на сервере, сокращая время генерации HTML.

Dynamic import можно использовать для компонентов с тяжелой логикой или интерактивностью:

const AsyncDialog = defineAsyncComponent(() =>
  import('element-plus/es/components/dialog')
);

Предзагрузка критических компонентов

Для элементов интерфейса, отображаемых выше «фолда» страницы, стоит использовать critical CSS и SSR для полного рендера на сервере, чтобы пользователь сразу видел готовый интерфейс.


Работа с Portal и Teleport

Element Plus активно использует Teleport для всплывающих компонентов (модальные окна, dropdown, popover). При SSR:

  • Teleport не выполняется на сервере, так как DOM отсутствует.
  • Для корректного рендера следует использовать условный рендеринг:


Это предотвращает ошибки гидратации и корректно рендерит интерфейс на сервере.


Управление состоянием и SSR

Компоненты Element Plus часто используют внутреннее состояние (ref, reactive). Для SSR:

  • Все данные должны быть инициализированы на сервере.
  • Передача состояния на клиент осуществляется через inlined state или Vuex / Pinia.

Пример передачи состояния:

const app = createSSRApp(App);
const store = createPinia();
app.use(store);

const html = await renderToString(app, {
  // встраиваем состояние store в HTML
});

Минимизация ошибок гидратации

Типичные ошибки:

  1. Несовпадение HTML между сервером и клиентом.
  2. Использование window/document на сервере.

Решения:

  • Проверка платформы через typeof window !== 'undefined'.
  • Изоляция браузерной логики в onMounted или client-only компоненты:

  
    {{ i }}
  

Рекомендации по производительности

  1. Серверный кешинг: кэшировать HTML и критические CSS для уменьшения времени ответа.
  2. Оптимизация стилей: использовать SCSS-переменные, отключать ненужные темы.
  3. Использование lazy hydration: тяжелые интерактивные компоненты и модальные окна загружаются только после монтирования клиента.
  4. Массивное использование поименного импорта: исключать из бандла ненужные компоненты.
  5. Минимизация Teleport/Portal: использовать только там, где это действительно необходимо.

Интеграция с Nuxt 3

Nuxt 3 поддерживает Element Plus через модуль @element-plus/nuxt. Ключевые настройки:

export default defineNuxtConfig({
  modules: ['@element-plus/nuxt'],
  elementPlus: {
    components: 'all', // можно использовать selective-import для уменьшения бандла
    importStyle: 'sass'
  }
});
  • SSR включен по умолчанию.
  • Важна настройка ssr: true для модулей и корректная инициализация Teleport.
  • Оптимизация критических стилей происходит автоматически через Nuxt Nitro.