Опыт перехода сайта на Single Page Application с упором на SEO

    Привет всем.


    Мы классический web 2.0 сайт сделаный на Drupal. Можно сказать, что мы медиа сайт, т.к. у нас очень много всевозможных статей, и постоянно выходят новые. Мы уделяем много внимания SEO. У нас для этого даже есть специально обученные люди, которые работают полный рабочий день.


    К нам заходит более 400k уникальных пользователей в месяц. Из них 90% приходит из поиска Google.


    И вот уже почти полгода мы разрабатывали Single Page Application версию нашего сайта.


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


    Перед тем как начать разработку мы начали исследовать этот вопрос.
    И выяснили, что общепринятым способом является отдача 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.example.com/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.example.com/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.example.com' + 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.example.com' + req.url).pipe(res);
    });

    sitemap.xml


    Т.к. sitemap.xml постоянно генерируется в Drupal, и адреса страниц совпадают с frontend, то было решено просто стримить sitemap.xml. Абсолютно также как с картинками:


    app.get('/sitemap.xml', function(req, res) {
      request('https://api.example.com/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.example.com адрес.
    А для Drupal версии зарезервировали дополнительный поддомен https://api.example.com/


    После чего, мы связали frontend чтобы он работал с https://api.example.com/ адресом.


    Релиз


    Сам релиз выглядит как простая перестановка местами серверов в DNS. Мы указываем наш текущий адрес @ на сервер frontend. После чего сидим, и смотрим как все работает.


    Тут стоит отметить, что если использовать CNAME записи, то замена сервера произойдет мгновенно. Запись A будет рассасываться по DNS до 48 часов.


    Производительность


    После разделения сайта на frontend и backend нагрузка на сервер стала размеренной. Также стоит отметить, что мы особо не оптимизировали sql запросы, все запросы проходят сквозь без кеширования. Вся оптимизация была запланирована уже после релиза.


    У меня не осталось метрики до релиза, зато есть метрика после того как мы откатились обратно :)


    Web transactions response time


    Throughput


    Top 5 database operations by wall clock time


    Database


    Views usage


    SEO


    Вот тут все оказалось не так хорошо, как хотелось бы. После чуть более недели тестирования трафик на сайт упал на 30%.


    google analytics


    Какие-то страницы выпали из индекса google, какие-то стали очень странно индексироваться, без meta description.


    Пример того, как Google проиндексировал вот эту страницу.
    missing meta


    Мы также заметили, что после релиза нового сайта Google заметил это, и начал а панике реиндексировать весь сайт. Тем самым обновив весь свой кэш.
    Crawl stats


    После чего Crawler нашел огромное количество старых страниц, которых уже давным давно не должно было быть в индексе.
    На графике ниже показан график найденый 404 страниц. Видно, что до релиза мы делали зачистку контента, и Google потихоньку удалял старые страницы. Но после релиза он начал это делать гораздо активнее.
    404's


    Результат / Выводы


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


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


    Одной из более вероятных версий является то, что у Google Crawler есть определенные ограничения. Это может быть память, либо время отрисовки страницы.


    Я сделал небольшой тест, создав страницу с секундомером, и попробовал отрисовать ее как crawler в Google Search Console. На скриншоте секундомер остановился на 5.26 секундах. Думаю crawler ждет страницу около 5 секунд, и потом делает снапшот, а все что загрузилось после — в индекс не попадает.


    reverse engineering of Google Crawler Bot


    Полезные ссылки



    Update


    • Добавил график из google analytics показывающий на как просел трафик.
    • Выяснил, что Google Crawler имеет около 5 секунд на отрисовку страницы.
    • Выяснил, что Google Crawler понимает когда обновляется сайт, и реиндексирует его.
    Share post
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More
    Ads

    Comments 93

      +8
      Просьба к людям людям сливающим мне карму и минусующим топик, объяснить с чем связана такая реакция?
        –4
        Я не могу сказать за тех кто минусовал, я не минусовал. Но вот подумайте, о чём ваша статья. Вот мы тут делали, делали и у нас не получилось? Ну и что? В чём новизна и интерес-то?
          +21
          Новизна в том, что Google официально отказались от SSR, а в интернете все еще нету никаких фидбэков на эту тему. Мы, как компания с относительно большим и серьезном сайтом, наступаем на эти грабли и даем вам фидбэк, бесплатно.
            –5
            Не минусовали, но фидбэк все же хотелось бы видеть в виде «проверили, реально с яваскриптом проблема у гугла, доказано так-то так-то и так-то» или даже "(то же самое) + проблема решается так-то и так-то", а у Вас лишь «попробовали обойтись без SSR, появились некоторые проблемы, с чем связано непонятно»:)
              –1
              Спасибо за ссылку на вики, объясняющая нерадивым умам, что такое одностраничный сайт. Благодарен за полезную статью, как только будет необходимость обращаться к drupal как rest сервису..., сразу же обращусь к этой статье, прямо по шагам буду идти.
              +9
              Человек поделился своим опытом. Сегодня многие делают SPA, вот что бы они не делали таких ошибок он и написал.
              Хотя согласен что не хватает продолжения и счастливого конца )
                +7
                Вспомните ошибку выжившего, читать сплошные success-story не особо полезно, порой куда интересней взглянуть на тех у кого не взлетело.
                0
                Спасибо за интересный фидбек. Гугл вообще ведёт себя непонятно, сначала они выпускают фреймворк для того что бы на нём что то пилили, а потом своим алгоритмом индексирования — убивают весь смысл использовать его для создания сайтов требующих SЕО. Тоесть по факту дла SPA остаються только админки, приложения на phoneGap и какие то комерческие системы чисто для автоматизации внутренней кухни у коркретных заказчиков. Можно конечно не смотря ни на что — делать сайты на ангулялре, но я ещё не видел людей которые были готовы вот так вот пожертвовать SEO ради того, что бы сайт был SPA.
                  0
                  Prerender.io наверное дешевле выйдет чем откат назад.
                    0

                    Откат назад, в нашем случае, это просто перемена адресов в DNS. Мы предполагали что надо будет откатываться назад.

                  0
                  А, собственно, в чем проблема сделать SSR на NodeJS? Берем phantomjs, и если в адресе есть _escaped_fragment_=, то прогоняем текущий адрес через phantomjs, убираем оттуда все JS скрипты и выдаем гуглу/яндексу/etc. Это же работы на час, максимум?
                    +3
                    У нас проблемы нету. Просто Google больше не рекомендует этот способ.
                      –3
                      Ну так можно же сделать SSR, а когда гугл научится окончательно хавать SPA, то убрать?

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

                      А рекомендует это гугл или нет, это не важно, пока это работает.
                        +8
                        Google также штрафует за то что для клиента и для бота отдаются две разные версии страницы. Зная то что Google более не рекомендует способ отрисовки отдельных страниц для бота, он может в один день начать штрафовать за это.

                        Как я уже сказал ранее, мы решили не делать SSR не потому что мы не можем, а по тому что Google сам отказался это этого метода. И мы решили попробовать скормить наш сайт без SSR. И выяснили что на сегодняшний день лучше все-таки использовать SSR.
                          –3
                          Ну у нас задачи немного разные :) Мы делали это больше для соц. сетей, нежели для гугла. А так, да. Отдаем лендинг как HTML страничку, без всяких там SPA.
                            –1
                            На сколько мне известно, Facebook не понимает JS, и для него нужно дополнительно отрисовывать странички.
                      +3
                      Разве отдача разного контента для разных User-Agent не считается клоакингом?
                        0

                        Не для разных User-Agent, а для разных _escaped_fragment_=. Мы так делали, всё отлично индексируется разными поисковиками. Более того, сайт давно мёртв, а ссылки всё ещё в индексе :-)

                          +2
                          В статье упомянуто об этом способе, а заодно указана ссылка на спеку в которой говорится что данный метод deprecated.
                            –4

                            И что? Он как работал так и будет работать. Причём работает он не только с гуглом. А если гугл когда-нибудь и выпилит его поддержку — ничего не сломается.

                              0
                              Да собственно ничего)
                              У меня есть сайт на angular работающий на данном способе. Но сейчас, с приходом react'а, я предпочитаю пререндерить страницу не только для SEO, но и для пользователей (что имеет свои плюсы). При этом например метод с _escaped_fragment_ не понимали боты соц. сетей и для них приходилось городить определение по user-agent'у на уровне nginx'a и перенапрявлять на тот же _escaped_fragment_.
                              В общем я за простоту, особенно если спека помечена как deprecated)
                      +5
                      Полезная, правильная статья. Человек описал свой опыт, явно неудачный. Тема важная. Очень хотелось бы получить комментарий от представителей гугла, иначе, к сожалению, так и остается непонятным, как же все-таки правильно отдавать результат поисковику.
                        +2

                        https://webmasters.googleblog.com/2015/10/deprecating-our-ajax-crawling-scheme.html


                        Кроме того, не стоит забывать, что гугл — не единственный поисковик.

                          0
                          Для нас — единственный. Суммарный трафик со всех остальных поисковиков менее 1%.
                            –9

                            Есть вы оптимизируете сайт исключительно под один поиск, то не удивительно, что через остальные вас попросту не находят. А после отказа от SSR вы и этих 4к пользователей в месяц потеряете.

                              +2

                              400k

                            0
                            Спасибо за ссылку. Да, это верно насчет гугла. Но все-таки это какая-то, извините, лажа получается. Допустим, я делаю одностраничный сайт, наполнение которого в браузере происходит ТОЛЬКО за счет JS. Ну как с ангуляром, загружаем данные, обновляем модель. Но вот же ж — поисковики не могут все это прочитать. И что тогда, вся эта прекрасная технология MVVM псу под хвост, потому что надо чтобы сайт индексировался или же приделывать какие-то костыли в виде дополнительного рендеринга только для поисковиков?
                              +1
                              Тут важно все разбить на страницы. Чтобы определенный контент показывался по определенным страницам.
                              Если все будет в одной куче — Google Crawler не поймет как это индексировать.
                          0
                          {
                          «status»: 301,

                          }

                          Зачем этот костыль? Есть же стандартные коды состояний HTTP.
                            0
                            Это не костыль, а статус запрашиваемой страницы. Я у backend спрашиваю состояние страницы, и он мне отвечает. Если backend мне вернет 503 — это будет означать что backend мертв, а не запрашиваемая страничка мертва.
                              0
                              Если не понятно — могу подробнее объяснить.
                                +2
                                Если честно, больше всего мне непонятно, зачем вообще в этой схеме nodejs. Только для того, чтобы отдавать стартовый index.html и редиректить?
                                  0
                                  Для того чтобы отрабатывать редиректы, 404 и стримить недостающие файлы с бэкэнда.
                                    0

                                    все это может продолжать делать друпал в режиме апи

                                      +1

                                      Нет, не может.


                                      1. У друпала слишком медленная инициализация, для того чтобы просто вернуть статику.
                                      2. Я не могу перегружать существующие адреса, т.к. они используются для модерации контента.
                                        +2
                                        Почему не делать отдачу статики и редирект со старых роутов на новые через nginx?
                                          0

                                          Я уже тут где-то отписал, по тому что у нас нету прямого доступа к серверам. Мы используем Heroku и Pantheon.

                                    0

                                    я вот тоже не понял, вначале подумал, что фронтенд полностью независим от друпала, у них просто общая база, но потом увидел, что весь контент все же отдает друпал через апи. В таком случае для Angular хватило бы просто статической странички в паблик-папке (не знаю, как точно в друпале это сделано, думаю, так же как и у всех остальных фреймворков)

                              0
                              Насколько я знаю, гугл хорошо умеет индексировать js сайты, но с одним условием, он не ждёт результатов ajax запросов. Поэтому если первичные данные для отрисовки любой страницы вы подтягиваете ajax'ом — гугл пройдёт мимо.
                                +1
                                А как иначе, если не подгружать данные? Это уже не JS сайт получается.
                                  0
                                  данные уже нужно подгрузить вместе с хтмл и использовать в виде
                                  <script>
                                  window.initialData = {};
                                  </script>
                                  


                                  Но естественно на каждую страницу не хочется в бекэнде прописывать какие данные должны быть в хтмл. Я решил эту проблему путём проверки вида запроса при обращении к странице, если запрос ajax — значит это реальный пользователь ходит туда сюда по сайту, если запрос get — значит это поисковик, соотвественно когда это поисковик, я запускаю phantomjs он идёт по этому же адресу (по user agent исключаем рекурсию) и ждём скажем 3 секунды, после этого ответ отдаём гуглу. По идее за три секунды все ajax'ы должны были отработать.
                                    0
                                    Правда если обычный человек зайдёт сразу на внутреннюю страницу, ему придётся ждать 3 секунды. Можно попробовать по user agent гугл ботов такую логику делать.
                                      +1

                                      Если данные передавать уже вшитыми в страницу, тогда эта страница будет очень долго отдаваться. Весь смысл перехода на JS пропадает.

                                        0
                                        Если оптимизируете SQL запросы, то оверхед не будет превышать 10мс.
                                          0

                                          А если все на ассемблере переписать, то ваще быстро будет.

                                            +2
                                            Я описал варианты решения, вам выбирать. В любом случае я не вижу логики быстро отдавать хтмл без самих данных и ждать пока аяксом они подгрузятся. Ведь так будет ещё дольше.
                                              +1

                                              Вовсе нет. Если данные отдельно подгружать, их можно закешировать как статику и положить в CDN. Что мы собственно и сделали.


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

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

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

                                    +1
                                    Он ждет. Но робот ограничен в этом ожидании, как и в оперативной памяти. Может часть высоконагруженной страницы просто недорендерить. Или не дождаться ответа от медленного АПИ. В общем черный ящик.
                                      0

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

                                    +6
                                    Интересный опыт. Не понял только зачем гонять картинки и sitemap.xml через node.js. У вас же наверняка наружу смотрит nginx, который может это делать лучше и с помощью конфигурации, без лишних строк кода.
                                      0

                                      К сожалению, у нас ни на backend ни на frontend нету прямого доступа к серверам. На frontend используется Heroku а на backend — Pantheon.

                                      +1
                                      Что такое v1 в robots.txt?
                                        0

                                        Это разрешение поисковым роботам на доступ к адресам вида /v1/*
                                        Этот префикс мы используем для REST API.

                                          +1
                                          А зачем индексировать api, это же программный интерфейс, а не человекочитаемый контент, за которым приходит гугл.
                                            0

                                            Если запретить api в robots.txt то Google бот не сможет загрузить данные для странички.

                                              0
                                              Это проверенная информация или гипотеза?
                                              Я вот, полагал, например, что сферический бот в вакууме, он да — при заходе на сайт ищет все ссылки и пытается их открыть, честно учитывая то что в robots.txt,
                                              Но когда у поисковиков пошёл тренд на поведенческие факторы, SPA, AJAX и т.п. я представлял себе, что они со своей стороны открывают страницу неким юзер-агентом приближенным к полноценному, которому, разумеется до robots.txt нет дела, если часть контента получается через AJAX.
                                                +1

                                                Да, это проверенная информация. Google Search Console ругается на это, если заблокировать, и страницу на предпросмотре показывает без данных.

                                        0
                                        Вот мы тоже повелись на это сообщение Гугла и даже проверили в Search Console что он сайт полностью показывает. А по факту оказалось, что он все равно только голый HTML индексирует. Пришлось в срочном порядке прикручивать prerender.io
                                          0

                                          Да, он там нам тоже все красиво показывает :)

                                          0

                                          На каждый запрос пользователя на новую версию вы внутри делаете https запрос на старую версию, чтобы вытянуть информацию по редиректам?
                                          При этом у вас response time для PHP в районе 70ms. Сколько времени из этого занимает https-запрос к старому бекенду за редиректом?

                                            0

                                            Верно, каждый запрос пользователя посылает запрос на старый backend. Единственное что, первый запрос делается с node.js для того чтобы отработать HTTP status code. Остальные запросы будут уходить с клиента.


                                            Сколько времени занимает https-запрос я сказать не могу, т.к. мы все это кэшируем в CloudFlare, и запрос на прямую не проходит. А он там уже по своему распределяет кэш по миру.

                                            0
                                            Статья свежая — значит самое время начать переписывать на Angular2, там с SEO в смысле сервер-сайд рендеринга все намного лучше
                                              0

                                              А angular 2 уже зарелизился?

                                                0
                                                Еще нет. Более того, там штатного SSR не было 2 месяца назад. Есть сторонее решение, но я его не проверял пока.
                                                  0
                                                  нет, пока в RC1. но если вы говорите что первую версию пол-года пилили, то сейчас как раз можно начинать
                                                    0

                                                    Мы ее делали на компонентах 1.5, так что мы готовимся к предстоящему обновлению. Как зарелизится 2.0 — так начнем, при условии что мы заставим Google индексировать наш контент.

                                                0
                                                У нас был API на php и фронтенд на ангуляре, то того момента пока это была исключительно админка для клиентов компании, вопроса о поисковиках вообще не стояло. А вот когда нужно было сделать публичный фронтенд к API, который бы индексировался поисковиками, решили сделать прототип с SSR на node.js + react.js. Суть в том что если юзер агент не может js, не зависимо от того краулер это или браузер, в котором отключили js, то все рендерится на сервере. Если же в браузере включен js, то пользователь работает с нормальным SPA.
                                                Как результат, яндекс и гугл проиндексировали все страницы, которые предполагались. Сайтик, который строит сайтмап автоматом, тоже без проблем это прожевал.
                                                За основу для прототипа брали вот эту репу github.com/erikras/react-redux-universal-hot-example
                                                  0

                                                  А как вы в версии без JS сделали авторизацию?

                                                    +1
                                                    Вопрос интересный ) На самом деле в прототипе пока никак, и не уверен что мы это будем делать, т.к. все-таки не предполагается что юзер будет полноценно работать с выключенным JS. Но если это очень надо, то ведь сабмит формы работает и без JS, так что я думаю особых проблем тут не будет.
                                                      0
                                                      Тогда придётся поддерживать две версии сайта, с JS и без. Для сабмитов надо будет ещё второстепенные страницы создавать.
                                                    0
                                                    А как вы определяли на уровне запроса идет он с js или без?
                                                      0
                                                      Если запрос пришел на бэк node.js, то значит у клиента нет js (или это первое обращение к сайту), рендерим все на сервере (используя нужные данные от API) и отдаем. Если же у клиента есть js, то все запросы будут уходить с фронта сразу к API, минуя бэкенд на node.js
                                                        0

                                                        NodeJS у вас выполняет презентационную функцию, а значит является фронтендом. А вот то, что вы называете "API" — и есть бэкенд.

                                                    0
                                                    После недели тестирования трафик на сайт упал на 30%

                                                    После отката трафик вернулся?
                                                      +1
                                                      Пока ещё нет. Но он перестал падать. Мы ещё следим за этим, на следующей неделе отпишу.
                                                      0
                                                      Как вариант — можно использовать вот эту разработку для поддержания SPA и HTML-static версии: prerender.io
                                                        0
                                                        Тут стоит отметить, что если использовать CNAME записи, то замена сервера произойдет мгновенно. Запись A будет рассасываться по DNS до 48 часов.

                                                        С чего бы это? Сколько ни вдумываюсь — не понимаю, в чём эффект: у каждой записи свой TTL (который подействует при следующем обновлении), откуда же у вас уверенность, что CNAME обновляется быстрее?
                                                          0

                                                          На сколько показывает моя практика, при использовании cloudflare, CNAME изменения применяются практически мгновенно, по сравнению с ALIAS. При открытой консоли приложения, можно увидеть что пользователи перестают обращаться к сайту.


                                                          Если делать тоже самое с ALIAS, при том же TTL, то это занимает какое-то время.

                                                          0
                                                          Лично мне статья показалась полезной в виду того, что информации по этой теме не так много. Веб приложения набирают популярность, а гугл не особо спешит их воспринимать. Сам столкнулся с этим, так пока и не нашел решения для себя. Пререндер выглядит уж больно временным решением, не хочется на нем концентрироваться. В идеале бы поторопить поисковики :) В общем спасибо за описание вашего опыта!
                                                            0
                                                            Если не секрет, какое решение вы нашли?
                                                              0
                                                              Мой проект написан на MeteorJS (https://github.com/InstaPhobia/instaphobia.com), я поставил сео-плагин, который генерирует мета-данные для страниц. По описанию и отзывам он вроде бы должен читаться как минимум гуглом, но в итоге на данный момент гугл в поиске показывет title, а description пустой. Так что, можно сказать, что я не нашел пока решение… Но на своем опыте тоже убедился, что с обработкой поисковиками одностраничных приложений пока «все не так прозаично» (см. «Да Здравствует Цезарь»), как они утверждают…
                                                                0
                                                                Спасибо за ответ. Вот ведь фигня. Одностраничным приложениям сто лет в обед, а поисковики упорно их игнорируют.
                                                                  0
                                                                  Получается, что так. Но по ощущениям, приложения должны быть еще популярнее со временем. Так что надеюсь, гугл тоже будет работать над этим. А там глядишь и Яндекс.
                                                                    0
                                                                    Учитывая тренды веб приложений, без SPA будет всё труднее обойтись, там глядишь и поисковики проснуться, начав решать нашу проблему более активно.
                                                                  0

                                                                  Мы тоже вставляем meta tags динамически через js. Попробуйте рисовать странички быстрее 5 секунд, я думаю это поможет.


                                                                  У нас все странички рисуются одинаково, разница лишь во времени отрисовки. И какие-то страницы все-таки попали в индекс, во всеми meta tags.

                                                                    0
                                                                    Спасибо, есть пища для размышлений. Буду экспериментировать.)
                                                              0
                                                              что же за спа у вас такой. За 5 секунд страницу не отрендить. Мда…
                                                                0

                                                                Это не только от фронтенда зависит.

                                                                0

                                                                Статья и комментарии кажутся очень любопытными даже спустя год. Расскажите, чем кончилась эта история? И какие лучшие практики для корректного индексирования SPA удалось сформулировать с тех пор? И в общем случае, и в случае конкретно вашей конфигурации?

                                                                  +1
                                                                  и меня тоже эти вопросы интересуют

                                                                Only users with full accounts can post comments. Log in, please.