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

Одностраничные приложения и их проблемы

Журнал trivago начинался как простой блог WordPress (WP) об интересных отелях и туристических направлениях. Мы использовали настраиваемую тему WP, которая обеспечивала правильную навигацию пользователя, а также SEO и дополнительные функции. Несмотря на то, что WP предлагает систему управления контентом, которая легко настраивается и может удобно использоваться большинством редакторов, она также вызывает множество проблем, таких как проблемы с производительностью, проблемы с масштабированием, трудная ремонтопригодность и многое другое.

В 2018 году команда разработчиков перешла с тем WP на журнал trivago Magazine, представленный в виде одностраничного приложения JavaScript (SPA) на основе WP REST API, чтобы изолировать внешнее приложение от внутреннего интерфейса WP. С этим шагом мы получили большую независимость в дизайне и реализации. Команда разработчиков была очень рада этому шагу и выбранному JavaScript-фреймворку Vue.js. Мы смогли внедрить множество новых функций за гораздо более короткое время без проблем с (внутренней) производительностью и масштабированием.

Поскольку SEO-трафик очень важен для журнала trivago Magazine, мы создали целевые HTML-страницы, содержащие SEO-теги и другие важные HTML-теги, и сохранили эти HTML-страницы в качестве точек входа для SPA. Однако ситуация с SPA и пользовательскими точками входа HTML по-прежнему была очень неудовлетворительной.

Из-за SPA и всего JavaScript поисковые системы, такие как Google, Bing и DuckDuckGo, а также сайты социальных сетей не всегда должным образом индексировали наши страницы. Чтобы Google и другие поисковые системы правильно проиндексировали SPA, необходимо каким-то образом отобразить его. Однако не все поисковые системы способны полностью отображать SPA. И даже для Google, который является одной из немногих поисковых систем, способных отображать веб-сайты JavaScript, чем больше он должен отображать, тем выше вероятность того, что некоторые страницы будут отображаться позже и, следовательно, не отображать содержимое страниц мгновенно. Это может негативно сказаться на ранжировании (см. также эту запись в блоге, чтобы получить представление о влиянии JavaScript на SEO). Ситуация усугублялась, когда наши контент-менеджеры журнала trivago Magazine вносили множество изменений в наши статьи, и поэтому многие страницы приходилось перерисовывать. В результате наш SEO-трафик упал.

Помимо проблем с SEO, большое количество JavaScript привело к тому, что наша оценка производительности PageSpeed ​​Insights, основанная на инструменте Lighthouse, значительно сместилась в красную зону. Наш показатель Time-To-Interactive значительно снизился. В частности, мобильные клиенты пострадали от большого количества JavaScript, потому что они часто не обладают той вычислительной мощностью, которая есть у настольных клиентов, а оценка производительности PageSpeed ​​Insights специально основана на подходе, ориентированном на мобильные устройства.

Рендеринг на стороне сервера — Nuxt.js нам в помощь

Помня об этих проблемах, мы начали придумывать новые идеи о том, как улучшить нашу ситуацию. Помимо нескольких небольших улучшений, наша основная идея заключалась в том, чтобы перейти от SPA — и, таким образом, рендеринга на стороне клиента (CSR) — к рендерингу на стороне сервера (SSR), сохранив нашу свободу, полученную путем отделения внешнего приложения от WP с помощью Vue. js.

В целом, SSR может улучшить SEO-трафик и производительность, поскольку весь контент уже отображается в виде исходного кода HTML и, таким образом, может отображаться быстрее в браузере клиента (см. также на этой странице обзор клиентской и серверной -Боковой рендеринг). Для реализации SSR существуют разные подходы. Одним из решений является предварительный рендеринг всего с помощью специального решения или с помощью Puppeteer, Rendertron или prerender.io. Веб-сайт Vue.js предлагает использовать либо vue-server-renderer и создать конфигурацию SSR самостоятельно, либо использовать специальные фреймворки, такие как Nuxt.js.

Nuxt.js — это фреймворк более высокого уровня поверх Vue.js, обеспечивающий отличный опыт разработки для написания универсальных приложений Vue.js. Таким образом, Nuxt.js позволяет работать в разных режимах: помимо типичного режима SPA для вашего приложения, вы можете выбирать между универсальным SSR и режимом предварительного рендеринга для вашего приложения. В универсальном режиме SSR ваш контент отображается как HTML на лету на основе HTTP-сервера Node.js. В режиме предварительного рендеринга ваш контент компилируется в статические HTML-файлы, содержащие необходимый код JavaScript, который затем можно сохранить на классическом HTTP-сервере.

Для журнала trivago мы решили использовать Nuxt.js. Мы просто хотели сосредоточиться на разработке приложений вместо создания подверженных ошибкам конфигураций SSR на основе базового Vue.js или даже перехода на совершенно другую структуру. Для краткого изложения преимуществ использования Nuxt.js мы ссылаемся на эту запись в блоге. Поскольку мы уже использовали Vue.js для журнала trivago раньше, переход с Vue.js на Nuxt.js не был большой проблемой с технической точки зрения.

Предварительный рендеринг — идеальное решение для журнала trivago

Когда мы начали работать с Nuxt.js, мы в конце концов решили использовать предварительный рендеринг, а не универсальный режим SSR для журнала trivago. Большая часть контента, создаваемого нашими контент-менеджерами в журнале trivago Magazine, является статической. Несмотря на то, что у нас также есть некоторый контент CSR в журнале trivago Magazine, нам обычно требуется предварительный рендеринг нашего контента только при добавлении, изменении или удалении статей или при добавлении, изменении или удалении функций приложения. По сути, у нас есть в основном статический контент, который позволяет нам использовать предварительный рендеринг, предоставляемый Nuxt.js.

Наконец, мы развертываем предварительно обработанный HTML и JavaScript журнала trivago Magazine в виде статических файлов HTML и JavaScript на AWS Simple Storage Service (S3) и подключаем AWS CloudFront — сеть доставки контента (CDN), предоставленную AWS, — к корзины AWS S3 для размещения журнала trivago (см., например, это руководство для получения дополнительной информации о размещении статически сгенерированного сайта Nuxt.js с использованием AWS S3 и CloudFront). AWS CloudFront предоставляет нашим клиентам HTTPS и правильно направляет трафик клиентов в AWS S3 для файлов HTML и JavaScript или в наш API журнала trivago для компонентов CSR Nuxt.js.

Для предварительного рендеринга компонентов Nuxt.js SSR журнала trivago Magazine мы используем конвейеры Jenkins, которые запускают предварительный рендеринг в пользовательских контейнерах Docker. При предварительном рендеринге нашего контента мы обращаемся к API trivago Magazine для извлечения контента, который предварительно визуализируется как статический HTML и JavaScript, который затем копируется в AWS S3. Мы настроили специальные триггеры для предварительного рендеринга содержимого журнала trivago при внесении изменений. Общая архитектура и этапы нашего подхода к предварительному рендерингу показаны на рисунке ниже.

В целом, наш подход к предварительному рендерингу на базе Nuxt.js и размещение журнала trivago Magazine через AWS S3 и AWS CloudFront обеспечивает нам очень экономичную и высокодоступную архитектуру, а также быструю доставку веб-сайта. Затраты на хранение и обслуживание HTML и JavaScript через AWS S3 и AWS CloudFront практически ничтожны. Однако недостатком является то, что у нас нет собственного настраиваемого веб-сервера. Возможности HTTP-сервера AWS S3 весьма ограничены. Но это намного перевешивает простота общей архитектуры.

Вывод

В журнале trivago Magazine мы используем Nuxt.js для создания наших компонентов SSR и CSR, для развертывания предварительно обработанных файлов HTML и JavaScript в AWS S3 и AWS CloudFront. При этом мы можем решить наши проблемы с производительностью SEO и JavaScript. В то же время мы также получаем очень экономичную и высокодоступную архитектуру. На рисунке ниже показано развитие Render-Start, Time-To-First-Byte и Availability of Magazine с течением времени. Вы можете увидеть падение Render-Start, когда мы развернули SSR-версию журнала в мае.

Хотя вы также можете выполнять SSR или предварительный рендеринг с другими фреймворками и инструментами или с собственной конфигурацией, основанной на простом Vue.js, мы решили выбрать Nuxt.js, потому что он позволяет вам сосредоточиться на реализации вашей бизнес-логики, а не построение сложных и, возможно, подверженных ошибкам конфигураций. Кроме того, Nuxt.js предоставляет вам свободу выбора между CSR и SSR для каждого компонента JavaScript.

Итак, если вы хотите получить выгоду от CSR и SSR для каждого компонента и хотите иметь для этого удобную структуру на основе Vue.js, команда разработчиков журнала trivago Magazine настоятельно рекомендует Nuxt.js для вашего приложения.

Первоначально опубликовано на https://tech.trivago.com 29 января 2020 г.