Vue.js — это платформа для создания клиентских приложений. По умолчанию компоненты Vue создают и манипулируют DOM в браузере в качестве вывода. Однако, также возможно преобразовать те же компоненты в строки HTML на сервере, отправить их непосредственно в браузер и, наконец, «гидратировать» статическую разметку в полностью интерактивное приложение на клиенте. Приложение Vue.js, отображаемое на сервере, также можно считать «изоморфным» или «универсальным» в том смысле, что большая часть кода вашего приложения выполняется как на сервере, так и на клиенте.
Почему SSR?
По сравнению с одностраничным приложением на стороне клиента (SPA) преимущество SSR в первую очередь заключается в:
- более быстром получении контента: это более заметно при медленном Интернете или медленных устройствах. Разметке, отображаемой на сервере, не нужно ждать, пока весь JavaScript будет загружен и выполнен для отображения, поэтому ваш пользователь увидит полностью визуализированную страницу раньше. Кроме того, выборка данных выполняется на стороне сервера при первом посещении, что, вероятно, обеспечивает более быстрое соединение с вашей базой данных, чем клиент. Обычно это приводит к улучшению показателей Core Web Vitals, улучшению пользовательского опыта и может иметь решающее значение для приложений, где время создания контента напрямую связано с коэффициентом конверсии.
- единой ментальной моделью: вы можете использовать один и тот же язык и одну и ту же декларативную, компонентно-ориентированную ментальную модель для разработки всего вашего приложения, вместо того, чтобы прыгать туда-сюда между внутренней системой шаблонов и внешней средой.
- лучшем SEO: сканеры поисковых систем будут напрямую видеть полностью отрисованную страницу.
Совет. На данный момент Google и Bing прекрасно индексируют синхронные приложения JavaScript. Ключевое слово здесь — синхронность. Если ваше приложение запускается со счетчиком загрузки, а затем извлекает контент через Ajax, сканер не будет ждать, пока вы закончите. Это означает, что если у вас асинхронно загружается контент на страницах, для которых важна SEO, может потребоваться SSR.
При использовании SSR также следует учитывать некоторые компромиссы:
- Ограничения развития. Код, специфичный для браузера, можно использовать только внутри определенных перехватчиков жизненного цикла; некоторым внешним библиотекам может потребоваться специальная обработка, чтобы их можно было запускать в приложении, отображаемом на сервере.
- Более сложные требования к настройке и развертыванию сборки. В отличие от полностью статического SPA, который можно развернуть на любом статическом файловом сервере, для приложения, отображаемого на сервере, требуется среда, в которой может работать сервер Node.js.
- Больше нагрузки на сервер. Рендеринг полного приложения в Node.js будет более ресурсоемким, чем просто обслуживание статических файлов, поэтому, если вы ожидаете высокий трафик, будьте готовы к соответствующей нагрузке на сервер и разумно используйте стратегии кэширования.
Прежде чем использовать серверный рендеринг vue js для своего приложения, первый вопрос, который вам следует задать: действительно ли он вам нужен. В основном это зависит от того, насколько важно время создания контента для вашего приложения. Например, если вы создаете внутреннюю панель мониторинга, где дополнительные несколько сотен миллисекунд при начальной загрузке не имеют большого значения, SSR будет излишним. Однако, в тех случаях, когда время доставки контента имеет решающее значение, SSR может помочь вам достичь максимально возможной производительности при начальной загрузке.
SSR против SSG
Статическая генерация сайта (SSG), также называемая предварительной визуализацией, — еще один популярный метод создания быстрых веб-сайтов. Если данные, необходимые для рендеринга страницы на сервере, одинаковы для каждого пользователя, то вместо рендеринга страницы каждый раз, когда поступает запрос, мы можем визуализировать ее только один раз, заранее, во время процесса сборки. Предварительно обработанные страницы генерируются и обслуживаются как статические HTML-файлы.
SSG сохраняет те же характеристики производительности, что и приложения SSR: он обеспечивает отличное время обработки контента. В то же время его дешевле и проще развертывать, чем приложения SSR, поскольку на выходе получается статический HTML и ресурсы. Ключевое слово здесь статическое: SSG можно применять только к страницам, потребляющим статические данные, то есть данные, которые известны во время сборки и не изменяются между развертываниями. Каждый раз, когда данные изменяются, требуется новое развертывание.
Если вы изучаете SSR только для улучшения SEO нескольких маркетинговых страниц (например, /, /about, /contact и так далее), то вам, вероятно, нужен SSG вместо SSR. SSG также отлично подходит для содержательных веб-сайтов, таких как сайты документации или блоги. Фактически, этот веб-сайт, который вы сейчас читаете, статически создан с помощью VitePress, генератора статических сайтов на базе Vue.
Рендеринг приложения
Давайте посмотрим на самый простой пример Vue SSR в действии.
- Создайте новый каталог и перейдите в него.
- Запустите npm init -y.
- Добавьте «type»: «module» в package.json, чтобы Node.js работал в режиме модулей ES.
- Запустите npm install vue.
- Создайте файл example.js:
// this runs in Node.js on the server.
import { createSSRApp } from 'vue'
// Vue's server-rendering API is exposed under `vue/server-renderer`.
import { renderToString } from 'vue/server-renderer'
const app = createSSRApp({
data: () => ({ count: 1 }),
template: `<button @click="count++">{{ count }}</button>`
})
renderToString(app).then((html) => {
console.log(html)
})
Затем запустите:
node example.js
В командной строке должно быть напечатано следующее:
<button>1</button>
Решения более высокого уровня
Переход от примера к готовому к использованию SSR-приложению требует гораздо большего. Нам понадобится: поддержка Vue SFC и другие требования к этапам сборки. Фактически нам нужно будет согласовать две сборки одного и того же приложения: одну для клиента и одну для сервера.
Совет. Компоненты Vue компилируются по-другому при использовании для SSR — шаблоны компилируются в конкатенации строк вместо функций рендеринга Virtual DOM для более эффективной производительности рендеринга.
В обработчике запросов сервера визуализируйте HTML с правильными ссылками на ресурсы на стороне клиента и оптимальными подсказками к ресурсам. Нам также может потребоваться переключиться между режимами SSR и SSG или даже смешать оба режима в одном приложении.
Управляйте маршрутизацией, получением данных и хранилищами управления состоянием универсальным способом.
Полная реализация будет довольно сложной и зависит от набора инструментов сборки, который вы выбрали для работы. Поэтому мы настоятельно рекомендуем использовать самоуверенное решение более высокого уровня, которое избавит вас от сложностей. Ниже мы представим несколько рекомендуемых решений SSR в экосистеме Vue.
- Nuxt
Nuxt — это платформа более высокого уровня, построенная на основе экосистемы Vue, которая обеспечивает оптимизированный процесс разработки для написания универсальных приложений Vue. А еще лучше, вы также можете использовать его в качестве генератора статических сайтов. Мы настоятельно рекомендуем это попробовать.
- Quasar
Quasar — это комплексное решение на основе Vue, которое позволяет использовать SPA, SSR, PWA, мобильное приложение, настольное приложение и расширение браузера, используя одну базу кода. Он не только выполняет настройку сборки, но также предоставляет полную коллекцию компонентов пользовательского интерфейса, совместимых с Material Design.
- Vite SSR
Vite предоставляет встроенную поддержку рендеринга на стороне сервера Vue, но она намеренно низкоуровневая. Если вы хотите использовать Vite напрямую, воспользуйтесь vite-plugin-ssr, плагином сообщества, который позволяет абстрагироваться от многих сложных деталей. Здесь вы также можете найти пример проекта Vue + Vite SSR с использованием ручной настройки, который может служить основой для дальнейшего развития. Обратите внимание, что это рекомендуется только в том случае, если у вас есть опыт работы с инструментами SSR/сборки и вы действительно хотите иметь полный контроль над архитектурой более высокого уровня.
Написание кода, дружественного к SSR
Независимо от ваших настроек сборки или выбора платформы более высокого уровня, существуют некоторые принципы, которые применяются во всех приложениях Vue SSR.
Реактивность на сервере
Во время SSR каждый URL-адрес запроса сопоставляется с желаемым состоянием нашего приложения. Никакого взаимодействия с пользователем и обновлений DOM нет, поэтому реактивность на сервере не требуется. По умолчанию реактивность во время SSR отключена для повышения производительности.
Перехватчики жизненного цикла компонентов
Поскольку динамических обновлений нет, перехватчики жизненного цикла, такие как onMounted или onUpdated, НЕ будут вызываться во время SSR и будут выполняться только на клиенте.
Вам следует избегать кода, который создает побочные эффекты, требующие очистки в setup() или корневой области <script setup>. Примером таких побочных эффектов является настройка таймеров с помощью setInterval. В коде только на стороне клиента мы можем установить таймер, а затем отключить его в onBeforeUnmount или onUnmounted. Но, поскольку перехватчики размонтирования никогда не будут вызываться во время SSR, таймеры останутся включенными навсегда.
Чтобы избежать этого, переместите код побочного эффекта в onMounted.
Доступ к API-интерфейсам, специфичным для платформы
Универсальный код не может предполагать доступ к API-интерфейсам, специфичным для платформы, поэтому, если ваш код напрямую использует глобальные переменные только для браузера, такие как окно или документ, они будут выдавать ошибки при выполнении в Node.js, и наоборот.
Для задач, которые совместно используются сервером и клиентом, но с разными API-интерфейсами платформы, рекомендуется обернуть реализации для конкретной платформы в универсальный API или использовать библиотеки, которые сделают это за вас. Например, вы можете использовать node-fetch, чтобы использовать один и тот же API выборки как на сервере, так и на клиенте.
Для API только для браузера общий подход заключается в ленивом доступе к ним внутри обработчиков жизненного цикла только для клиента, таких как onMounted. Обратите внимание: если сторонняя библиотека не написана с учетом универсального использования, ее может быть сложно интегрировать в приложение, отображаемое на сервере. Возможно, вам удастся заставить его работать, имитируя некоторые глобальные переменные, но это будет хакерски и может помешать коду определения среды других библиотек.
Вывод
В заключение можно подвести итоги о значении и преимуществах использования серверного рендеринга (SSR) в разработке приложений на Vue.js. SSR позволяет улучшить производительность приложения за счет предварительной отрисовки страниц на сервере перед отправкой на клиент, что увеличивает скорость загрузки и улучшает SEO-оптимизацию. Это особенно важно для проектов, где важна скорость загрузки и индексация контента поисковыми системами.
Преимущества использования SSR в Vue.js включают в себя лучшую оптимизацию производительности, повышение SEO-показателей, улучшенную пользовательскую интерактивность и лучшую поддержку для социальных сетей при обмене ссылками на содержимое.
Для дальнейшего изучения и применения SSR в проектах на Vue.js рекомендуется:
- Изучить документацию Vue.js и понять основные принципы работы серверного рендеринга.
- Провести практические эксперименты с реализацией SSR в своих проектах для лучшего понимания механизмов работы.
- Изучить возможности оптимизации SSR для улучшения производительности и пользовательского опыта.
- Следить за последними тенденциями и лучшими практиками в области SSR, чтобы эффективно применять их в своих проектах.
Таким образом, использование серверного рендеринга в Vue.js может значительно улучшить производительность и оптимизацию приложений, что делает его важным инструментом для разработчиков, стремящихся к созданию быстрых, масштабируемых и оптимизированных веб-приложений с высоким уровнем пользовательского опыта!
Остались вопросы о серверном рендеринге (SSR) в Vue.js? Спрашивайте в комментариях ниже!