Четверг, 31 января 2019 г.
Многие фреймворки, используемые при создании сайтов, основаны на JavaScript. Из-за этого роботам Google может требоваться много времени на индексирование вашего контента, в том числе обновленных материалов.
На конференции Google I/O в 2018 г. мы обсудили один из способов решения этой проблемы – динамическую отрисовку. Реализовать эту функцию можно различными способами, например с помощью Rendertron – инструмента с открытым кодом, основанного на консольном браузере Chromium. Этот способ описан ниже.
В каких случаях стоит использовать динамическую отрисовку
Не все роботы поисковых систем и социальных сетей способны выполнять код JavaScript на веб-страницах. Например, робот Googlebot зачастую тратит на это много времени и при этом не может интерпретировать некоторые элементы JavaScript.
Мы рекомендуем использовать динамическую отрисовку при работе с часто обновляемым контентом, для показа которого требуется JavaScript. Чтобы сделать ваш сайт более удобным для посетителей, например ускорить первую значимую отрисовку, попробуйте использовать гибридную отрисовку. В частности, для этого подходит технология Angular Universal.
Как работает динамическая отрисовка
Динамическая отрисовка позволяет предоставлять некоторым агентам пользователя контент страницы, предварительно обработанный на сервере.
Для выполнения кода JavaScript и создания статических HTML-страниц мы будем использовать Rendertron – отрисовщик с открытым исходным кодом, основанный на консольном браузере Chromium. Одностраничные приложения часто загружают данные в фоновом режиме или делают паузу, чтобы выполнить отрисовку контента. Rendertron использует алгоритмы, позволяющие определять, завершил ли сайт отрисовку контента. Он ожидает завершения всех сетевых запросов и операций обработки.
В этой публикации мы рассмотрим:
- Пример веб-приложения.
- Создание небольшого сервера на
express.js
для работы веб-приложения. - Установку и настройку 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.
- Создайте проект в Google Cloud Console. Обратите внимание на идентификатор проекта под полем для ввода названия.
- Установите Google Cloud SDK согласно инструкциям и выполните вход.
-
Клонируйте проект 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
- Выберите нужный регион и подтвердите развертывание. Дождитесь завершения процесса.
- Введите 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-версию веб-приложения.