Досвід переходу сайту на Single Page Application з упором на SEO

Привіт всім.
Ми класичний web 2.0 сайт зроблений на Drupal. Можна сказати, що ми медіа сайт, тому що у нас дуже багато всіляких статей, і постійно виходять нові. Ми приділяємо багато уваги SEO. У нас для цього є спеціально навчені люди, які працюють повний робочий день.
До нас заходить більше 400k унікальних користувачів в місяць. З них 90% приходить з пошуку Google.
І ось вже майже півроку ми розробляли Single Page Application версію нашого сайту.
Як ви вже напевно знаєте, JS це вічна біль сеошників. І не можна просто так взяти і зробити сайт на PHP.
Перед тим як почати розробку ми почали досліджувати це питання.
І з'ясували, що загальноприйнятим способом є віддача google боту вже отрисованой версії сторінки.
Making AJAX applications crawlable
Також з'ясувалося, що цей спосіб більше не рекомендується Google і вони запевняють, що їх бот вміє відкривати js сайти, не гірше сучасних браузерів.
We are generally able to render and understand your web pages like modern browsers.
оскільки на момент прийняття нашого рішення Google тільки-тільки відмовилися від подібного методу, і ще ніхто не встиг перевірити як Google Crawler насправді індексує сайти зроблені на JS. Ми вирішили ризикнути і зробити SPA сайт без додаткової відтворення сторінок для ботів.
— Навіщо?
З-за нерівномірного навантаження на сервера, і неможливості гнучко оптимізувати сторінки, було вирішено розділити на сайт backend (поточна версія на Drupal) та frontend (SPA на AngularJS).
Drupal буде використовувати виключно для модерації контенту і відправки всілякої пошти.
AngularJS буде малювати все, що повинно бути доступно користувачам сайту.
Технічні подробиці
В якості сервера для frontend було вирішено використовувати Node.js + Express.
REST Server
З Drupal зробили REST сервер, просто створивши новий префікс /v1/тобто всі запити, що приходять на /v1/ сприймалися як запити до REST. Всі інші адреси залишилися без зміни.
Адреси сторінок
Для нас дуже важливо, щоб всі публічні сторінки жили на тих адресах, як і раніше. З цього ми перед розробкою SPA версії структуризировали всі сторінки, щоб вони мали спільні префікси. Наприклад:
Всі forum сторінки повинні жити за адресою /forum/*, при цьому у форуму є категорії і самі топіки. Для них url буде виглядати наступним чином
/forum/{category}/{topic}
. Не повинно бути ніяких випадкових сторінок за випадковим адресами, все повинно бути логічно структуровано.
Redirects
Сайт доступний з 2007 року, і за цей час дуже багато чого змінилося. В тому числі адреси сторінок. У нас збережена вся історія, як сторінки переїжджали з однієї адреси на інший. І при спробі запросити який-небудь старий адресу ви будете переправлені на новий.
Для того щоб новий frontend також перенаправляв, ми перед відображенням сторінки в nodejs відправляємо запит назад в Drupal, і запитуємо який стан запитуваної адреси. Виглядає ось так:
curl -X GET-header 'Accept: application/json' 'https://api.wikijob.co.uk/v1/path/lookup?url=node/1'

На що Drupal відповідає:
{
"status": 301,
"url": "/content/industry/accountancy-professional-services/accountancy-professional-services"
}

Після чого nodeJS вирішує залишатися на поточному адресу, якщо це 200, або зробити редирект на іншу адресу.
app.get('*', function(req, res) {
request.get({url: 'https://api.wikijob.co.uk/v1/path/lookup', qs: {url: req.path}, json: true}, function(error, response, data) {
if (!error && data.status) {
switch (data.status) {
case 301:
case 302:
res.redirect(data.status, 'https://www.wikijob.co.uk' + data.url);
break;

case 404:
res.status(404);

default:
res.render('index');
}
}
else {
res.status(503);
}
});
});

Images
В контенті прийшов з Drupal можуть бути файли, які не існують в frontend версії. З цього ми вирішили просто стримить їх з Drupal через nodejs.
app.get(['*.png', '*.jpg', '*.gif', '*.pdf'], function(req, res) {
request('https://api.wikijob.co.uk' + req.url).pipe(res);
});

sitemap.xml
Т. к. sitemap.xml постійно генерується в Drupal, і адреси сторінок збігаються з frontend, то було вирішено просто стримить sitemap.xml. Абсолютно так само, як з картинками:
app.get('/sitemap.xml', function(req, res) {
request('https://api.wikijob.co.uk/sitemap.xml').pipe(res);
});

Єдине, на що варто звернути увагу, це на те, щоб Drupal підставляв правильну адресу сайту, який використовується на frontend. Там є налаштування в адмінці.
robots.txt
  • Доступний для google crawler bot контент не повинен дублюватися між нашими двома серверами.
  • Весь запитуваний через frontend у Drupal контент повинен бути доступний для перегляду ботом.
В результаті чого наші robots.txt виглядають наступним чином:
В Drupal заборонити всі крім /v1/:
User-agent: *
Disallow: /
Allow: /v1/

У frontend просто дозволити все:
User-agent: *

Підготовка до релізу
Перед релізом ми помістили frontend версію на https://new.wikijob.co.uk адреса
А для Drupal версії зарезервували додатковий піддомен https://api.wikijob.co.uk/
Після чого, ми зв'язали frontend щоб він працював з https://api.wikijob.co.uk/ адресою.
Реліз
Сам реліз виглядає як проста перестановка місцями серверів DNS. Ми вказуємо наш поточний адресу @ на сервер frontend. Після чого сидимо і дивимося як все працює.
Тут варто відзначити, що якщо використовувати
CNAME
записи, то заміна сервера відбудеться миттєво. Запис
A
буде розсмоктуватися DNS до 48 годин.
Продуктивність
Після поділу сайту на frontend і backend навантаження на сервер стала розміреним. Також варто зазначити, що ми особливо не оптимізували sql запити, всі запити проходять крізь без кешування. Вся оптимізація була запланована вже після релізу.
У мене не залишилося метрики до релізу, зате є метрика після того як ми відкотилися назад :)
Web transactions response time
web transactions response time
Throughput
Throughput
Top 5 database operations by wall clock time
Top 5 database operations by wall clock time
Database
Database
Views usage
Views usage
SEO
Ось тут все виявилося не так добре, як хотілося б. Після тижня тестування трафік на сайт впав на 30%, якісь сторінки випали з індексу google, які стали дуже дивно індексуватися, без meta description.
missing meta
Результат / Висновки
З-за проблем з індексуванням було прийнято рішення відкотитися назад на Drupal, і думати що ми зробили не так.
Все ускладнюється тим, що google є якоюсь чорною коробкою, що якщо щось йде не так просто видаляє сторінки з індексу. І будь-які наші експерименти вимагають пари днів, щоб це відбилося на результатах пошуку.
Однією з більш вірогідних версій, якою ми зараз дотримуємося, це те що google хоч і вміє, але все ще не досить добре індексує js. І ми будемо пробувати робити Server-Side Rendering.
Корисні посилання
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.