Nuxt: скорость и seo для интернет-магазина
Оба фактора влияют на ранжирование в поисковой выдаче, а отдельно скорость предопределяет поведение пользователей. Алгоритм наилучшего быстродействия и прохождения индексации программисты закладывают в архитектуре ит-продукта.
Сейчас мы работаем над e-commerce платформой для большой розничных магазинов. Это площадка с более чем 20-ю тысячами товаров. Привычное для нас и клиента решение — магазин на базе Битрикса — не подходило для проекта. И мы обратили свое внимание на Nuxt.
Почему Nuxt, а не Vue?
Nuxt — фреймворк на основе Vue.js для создания универсальных приложений — предлагает принципиально другой подход к работе с frontend-ом сайта.
Nuxt поддерживает SSR, server side rendering. Эта технология рендеринга сайта увеличивает скорость загрузки и позволяет поисковикам корректно индексировать страницы:
- Скорость. Во Vue.js весь рендеринг страницы происходит на стороне браузера. За расчет и отрисовку графических элементов отвечает клиентская сторона — локальный браузер компьютера, телефона, планшета. Пользователь увидит страницу сайта только после полной подгрузки скриптов. SSR же перекидывает рендеринг на сервер, а клиентской стороне отдает сначала HTML-страницу, она сразу отображается у пользователя в браузер, потом подгружает скрипты. То есть пользователь взаимодействует с контентом раньше, чем при разработке на Vue.js. Очевидно, что нагрузка на браузер меньше, скорость загрузки быстрее.
- Seo. Для продвижения важнее всего первая загрузка сайта. Если поисковой робот зайдет на сервис на чистом Vue.js, то первым увидит пустой HTML-документ без контента. Потому что при начальной загрузке подключился только js скрипт, где записано все приложение, а уже потом скрипт динамически подгрузил сайт. Роботы не поняли, что это за ресурс, ушли, интернет-магазин остался без проиндексированных страниц. Рендеринг на сервере, как в Nuxt, при первой загрузке сразу формирует понятный HTML. Поисковики воспринимают страницу как обычный документ со всеми разделами, контентом, метаданными и корректно индексируют сайт.
Связка с Битриксом
В чем была главная загвоздка сделать интернет-магазин полностью на Битриксе? Страница загружалась полностью при любом обновлении. Для всех элементов формировались запросы и отправлялись в базу данных. В не зависимости должен поменяться футер, хедер или контент после пользовательского действия или нет — из backend’а прилетает HTML и меняет весь интерфейс. Да, поисковые роботы всегда смогут просканировать HTML и понять содержимое страницы, но скорость загрузки из-за постоянного обновления очень хромала. Можно кэшировать отдельные части, чтобы не делать запросы к базе данных. В теории это увеличит скорость. Но нам все равно придется получать HTML этих данных из кэша и отправлять их на front. Все операции требуют ресурсов.
Поэтому frontend мы отдали Nuxt-у, а Битрикс остался на backend-е. Он предлагает огромное количество готовых функций для интернет-магазинов: эквайринг, кассы, скидки, остатки, склады. Кастомная реализация таких инструментов возможна, допустим на Laravel, но требует больше времени. Поэтому Битрикс используем на backend-е и взаимодействуем с ним через REST API.
Финальный аргумент в пользу связки Nuxt+Битрикс — полное разделение frontend и backend разработки. Во-первых, программисты могут выбрать один вектор работы и полноценно развиваться в нем. Во-вторых — тестирование. Разграничение позволит проводить интеграционные или unit-тесты отдельно для front-а и back-а, единичных сервисов, что в Битрикс сделать крайне сложно и неудобно.
Сложности
Основной сложностью стала длительность первой загрузки страницы. Мы рассчитывали на скорость быстрее Битрикса, а вышло дольше. Почему?
Предположим, что для первой страницы нужно обработать три запроса:
- список товаров по фильтру;
- список фильтров для товаров;
- список разделов.
Если бы интернет-магазин был полностью на Битрикс, то процесс передачи данных выглядел так. Битрикс загружает данные по первому запросу, выполняется РНР скрипт, который идет последовательно: инициализирует классы, кэширует значения. Обработка первого запроса будет долгой, предположим, 0,15 секунды: 0,12 — инициализация ядра, 0,3 — запрос. Второй и третий будет обработан быстрее, потому что есть кэш. Предположим по 0,3 секунды. В сумме получаем загрузку первой страницы за 0,21 секунды.
Для нашей связки Nuxt+Битрикс был план — реализовать REST API, опираясь на лучшие практики. Каждый блок на странице отправляет свой запрос к Битриксу. Но получить блоки мы могли тоже только по отдельности. На формирование страницы целиком уходило от трех до пяти запросов. То есть: первый запрос — Битрикс инициализирует ядро и кэширует переменные, отдает Nuxt-у, второй запрос — Битрикс инициализирует ядро и кэширует переменные, отдает Nuxt-у, третий запрос — Битрикс инициализирует ядро и кэширует переменные, отдает Nuxt-у и так далее.
Получается, что загрузка первой страницы в связке Битрикс+Nuxt занимала 0,45 секунды. Это была глобальная проблема. Долгая первая загрузка — плохая индексация роботами, быстрый отток пользователей.
Решение проблемы нашли в объединении. Мы организовали отдельный слой REST API, который группирует запросы. От Nuxt к back-у идут не отдельные просьбы «дай мне разделы по фильтру X», «дай мне список товаров по фильтру X», а одна — «дай мне страницу товаров, в которую входят товары и разделы по фильтру X». Внутри основного REST API, которое обращается напрямую к Битриксу, базе данных, запросы разбиты в соответствии с лучшими практиками.