Physical Address

304 North Cardinal St.
Dorchester Center, MA 02124

Динамическая отрисовка с помощью Rendertron

Многие фреймворки, используемые при создании сайтов, основаны на JavaScript. Из-за этого роботам Google может требоваться много времени на индексирование вашего контента, в том числе обновленных материалов.

На конференции Google I/O в 2018 г. мы обсудили один из способов решения этой проблемы – динамическую отрисовку. Реализовать эту функцию можно различными способами, например с помощью Rendertron – инструмента с открытым кодом, основанного на консольном браузере Chromium. Этот способ описан ниже.

В каких случаях стоит использовать динамическую отрисовку

Не все роботы поисковых систем и социальных сетей способны выполнять код JavaScript на веб-страницах. Например, робот Googlebot зачастую тратит на это много времени и при этом не может интерпретировать некоторые элементы JavaScript.

Мы рекомендуем использовать динамическую отрисовку при работе с часто обновляемым контентом, для показа которого требуется JavaScript. Чтобы сделать ваш сайт более удобным для посетителей, например ускорить первую значимую отрисовку, попробуйте использовать гибридную отрисовку. В частности, для этого подходит технология Angular Universal.

Как работает динамическая отрисовка

Динамическая отрисовка позволяет предоставлять некоторым агентам пользователя контент страницы, предварительно обработанный на сервере.

Для выполнения кода JavaScript и создания статических HTML-страниц мы будем использовать Rendertron – отрисовщик с открытым исходным кодом, основанный на консольном браузере Chromium. Одностраничные приложения часто загружают данные в фоновом режиме или делают паузу, чтобы выполнить отрисовку контента. Rendertron использует алгоритмы, позволяющие определять, завершил ли сайт отрисовку контента. Он ожидает завершения всех сетевых запросов и операций обработки.

В этой публикации мы рассмотрим:

  1. Пример веб-приложения.
  2. Создание небольшого сервера на express.js для работы веб-приложения.
  3. Установку и настройку Rendertron в качестве промежуточного ПО для динамической отрисовки.

Пример веб-приложения

Веб-приложение Kitten Corner с помощью JavaScript получает от API разнообразные изображения кошек и располагает их на странице в виде сетки.

Вот его код JavaScript:

const apiUrl = 'https://api.thecatapi.com/v1/images/search?limit=50';
   const tpl = document.querySelector('template').content;
   const container = document.querySelector('ul');
   function init () {
     fetch(apiUrl)
     .then(response => response.json())
     .then(cats => {
       container.innerHTML = '';
       cats
         .map(cat => { const li = document.importNode(tpl, true); li.querySelector('img').src = cat.url; return li;
         }).forEach(li => container.appendChild(li));
     })
   }
   init();
   document.querySelector('button').addEventListener('click', init);

В этом веб-приложении используется современная версия JavaScript (ES6), которую пока не поддерживает робот Googlebot. Чтобы узнать, виден ли этому роботу контент, проверим оптимизацию для мобильных устройств:

Эту проблему легко решить, однако сейчас у нас другая задача – научиться настраивать динамическую отрисовку. Благодаря ей робот Googlebot сможет обрабатывать изображения кошек, в то время как код веб-приложения останется прежним.

Настройка сервера

При помощи библиотеки express для node.js мы создадим веб-сервер для нашего приложения.

Ниже приведен код сервера (вы также можете ознакомиться с полным кодом проекта).

const express = require('express');
const app = express();
const DIST_FOLDER = process.cwd() + '/docs';
const PORT = process.env.PORT || 8080;
// Serve static assets (images, css, etc.)
app.get('*.*', express.static(DIST_FOLDER));
// Point all other URLs to index.html for our single page app
app.get('*', (req, res) => {
  res.sendFile(DIST_FOLDER + '/index.html');
});
// Start Express Server
app.listen(PORT, () => {
  console.log(`Node Express server listening on https://localhost:${PORT} from ${DIST_FOLDER}`);
});

Попробуйте открыть опубликованную версию веб-приложения. Если вы пользуетесь современным браузером, то увидите подборку изображений кошек. Чтобы запустить это приложение на своем компьютере, вам понадобится node.js. Введите следующие команды:

npm install --save express rendertron-middleware
node server.js

Откройте в браузере страницу https://localhost:8080. Теперь можно настраивать динамическую отрисовку.

Развертывание экземпляра Rendertron

Rendertron запускает сервер, который принимает URL и возвращает статический HTML-код, используя консольный браузер Chromium. Мы последуем рекомендации от участников проекта Rendertron и воспользуемся сервисом Google Cloud Platform.

Вы можете начать с бесплатного тарифа, однако использование таких решений для реальных задач может повлечь расходы в соответствии с расценками Google Cloud Platform.

  1. Создайте проект в Google Cloud Console. Обратите внимание на идентификатор проекта под полем для ввода названия.
  2. Установите Google Cloud SDK согласно инструкциям и выполните вход.
  3. Клонируйте проект Rendertron с сайта GitHub:
git clone https://github.com/GoogleChrome/rendertron.git
cd rendertron

Выполните следующие команды, чтобы установить зависимости и собрать Rendertron на своем компьютере:

npm install && npm run build

Активируйте кеш Rendertron, создав в каталоге rendertron файл под названием config.json со следующим содержанием:

{ "datastoreCache": true }

Выполните приведенную ниже команду в каталоге rendertron. Вместо YOUR_PROJECT_ID введите идентификатор своего проекта (см. шаг 1).

gcloud app deploy app.yaml --project YOUR_PROJECT_ID
  1. Выберите нужный регион и подтвердите развертывание. Дождитесь завершения процесса.
  2. Введите URL проекта (YOUR_PROJECT_ID.appspot.com). После этого должен появиться интерфейс Rendertron с полем ввода и несколькими кнопками.

Если вы видите веб-интерфейс Rendertron, значит ваш собственный экземпляр этого инструмента успешно развернут. Сохраните URL своего проекта (YOUR_PROJECT_ID.appspot.com), так как он понадобится вам на следующем шаге.

Добавление Rendertron на сервер

Веб-сервер использует express.js, а в Rendertron есть промежуточное ПО для express.js. Выполните следующую команду в каталоге, содержащем файл server.js:

npm install --save rendertron-middleware

Эта команда установит из nmp промежуточное ПО rendertron-middleware, которое затем можно будет добавить на сервер, как показано в примере ниже:

const express = require('express');
const app = express();
const rendertron = require('rendertron-middleware');

Настройка списка роботов

Чтобы определить, является ли источником запроса браузер или робот, Rendertron анализирует HTTP-заголовки user-agent и сравнивает их с собственным актуальным списком роботов. По умолчанию в этом списке нет робота Googlebot, поскольку он способен интерпретировать код JavaScript. Чтобы запросы от этого робота также обрабатывались с помощью Rendertron, добавьте его в список с помощью следующего кода:

const BOTS = rendertron.botUserAgents.concat('googlebot');
const BOT_UA_PATTERN = new RegExp(BOTS.join('|'), 'i');

Теперь Rendertron будет сравнивать заголовок user-agent также и с этим регулярным выражением.

Добавление промежуточного ПО

Чтобы отправлять запросы роботов своему экземпляру Rendertron, нам нужно добавить промежуточное ПО на сервер express.js. Это ПО проверяет, какой агент пользователя указан в соответствующем HTTP-заголовке, и перенаправляет запросы от известных роботов экземпляру Rendertron. Добавьте приведенный ниже код в файл server.js и не забудьте заменить элемент YOUR_PROJECT_ID на идентификатор своего проекта в сервисе Google Cloud Platform.

app.use(rendertron.makeMiddleware({
  proxyUrl: 'https://YOUR_PROJECT_ID.appspot.com/render',
  userAgentPattern: BOT_UA_PATTERN
}));

Роботы, запрашивающие упомянутый в нашем примере сайт, смогут получать статические HTML-страницы от Rendertron и не должны будут обрабатывать код JavaScript для показа контента.

Тестирование

Чтобы выяснить, правильно ли реализовано решение Rendertron, ещё раз выполните проверку оптимизации для мобильных устройств.

В отличие от результатов первой проверки, сейчас изображения должны быть видны. На вкладке «HTML» представлен весь HTML-код, созданный при выполнении JavaScript. Благодаря Rendertron роботу не нужно выполнять JavaScript для показа контента.

Заключение

Мы настроили динамическую отрисовку, ничего не меняя в веб-приложении, и теперь можем предоставлять поисковым роботам статическую HTML-версию веб-приложения.