На своем проекте я использую 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()
Иначе придется ждать истечения срока хранения кэша, чтобы изменения закэшировались и поисковики стали получать их.