Поднимаем Prerender для индексации SPA

На своем проекте я использую NodeJS и AngularJS. В выборе пути решения проблемы индексации одностраничного приложения (single page aplication или SPA) я остановился на
Prerender. Это опенсорсный проект, который активно развивается и постоянно обновляется. Можно воспользоваться их сервисом и не напрягаться. До 250 страниц бесплатно. Если больше, то придется заплатить. Но мы идем другим путем. Разворачиваем свой сервер Prerender и настраиваем кэширование страниц в MongoDB.

У нас уже должна быть поднята mongoDB и подобающе настроен наш фронтэнд.

Изменения в своем приложении

На своем сервере ставим prerender-node командой:

npm install prerender-node --save

и в своем файле expressjs сервера прописываем:

app.use(require('prerender-node'));

Теперь мы будем отлавливать запросы от поисковых и прочих ботов. Для таких запросов получаем HTML-снимок страницы от сервера prerender и этот html-файл отправляем боту.

Еще нужно задать переменную среды с адресом нашего prerender сервера. Наше приложение работает на порту 3000, а prerender будет запущен на 3001:

export PRERENDER_SERVICE_URL="http://localhost:3001/"

Prerender сервер

Рядом с директорией своего сервера выполним команды:

git clone https://github.com/prerender/prerender.git
cd prerender
npm install

Укажем с помощью переменной среды, что запускаться он должен на порту 3001:

export PORT=3001

И запустим его:

node server.js

Уже должно работать. Протестируем. Попробуем в браузере открыть адрес своего сайта с добавлением ?_escaped_fragment_=

http://www.example.com/?_escaped_fragment_=

Мы должны увидеть нужную нам страницу. Весь html-код сгенерирован на сервере и из него вырезаны <script>-тэги. Однако удручает время загрузки, которое может составлять 1,5 секунды и более. Рендер страницы на сервере занимает существенную его часть. А поисковики сейчас борются за скорость открытия страниц и за долгие загрузки могут штрафовать. Поэтому настроим кэширование страниц в базе данных mongodb.

Кэширование в mongodb

Для реализации кэширования страниц в mongodb разработчики prerender в своем readme рекомендуют плагин prerender-mongodb-cache. Однако у меня не вышло его заставить работать без напильника, ибо он давненько не обновлялся, а последние обновления даже не залиты в npm. Пришлось форкнуть и немного допилить его: обновить пакеты, добавить функционал срока хранения страниц в кэше.

Для установки модуля переходим в директорию prerender:

cd prerender

и устанавливаем npm-пакет из github:

npm i https://github.com/twoheaded/prerender-mongodb-cache.git --save

В корне prerender находится файл server.js, в котором нужно добавить следующую строку:

server.use(require('prerender-mongodb-cache'));

По умолчанию срок хранения закэшированных страниц - 7 дней. Можно задать необходимое значение в переменной среды CACHE_EXPIRATION_DAYS (в днях).

Попробуем открыть наш сайт:

http://www.example.com/?_escaped_fragment_=

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

Подключение к БД по умолчанию производится локально по адресу mongodb://localhost/prerender. Изменить путь можно задав переменные среды MONGOLAB_URI или MONGOHQ_URL. Закэшированные страницы будут храниться в коллекции pages.

После внесения каких-либо больших изменений в части фронтэнда рекомендую удалять данную коллекцию:

mongo
use prerender
db.pages.drop()

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