Prerender



    Open Source решение для полноценной поисковой индексации ваших JavaScript приложений (Backbone, Angular, Ember, ChaplinJS, Marionette). Работает это следующим образом:

    1. Мидлвар на Ruby on Rails или Node.js проверяет user agent при каждом запросе к приложению
    2. Если обнаружен краулер поисковой машины то отправляется GET запрос к Prerender
    3. Prerender вызывает ваше приложение для той страницы, которую запрашивает краулер
    4. Страница рендерится с помощью PhantomJS
    5. Полученный HTML посылается обратно
    6. Мидлвар возвращает HTML краулеру


    Node.js

    $ npm install prerender-node --save
    

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

    Ruby on Rails

    gem 'prerender_rails'
    

    config.middleware.use Rack::Prerender
    


    Большое спасибо всем за внимание.
    Поделиться публикацией

    Комментарии 33

      –7
      Не понимаю, для каких это поисковиков предназначенно? Неужели яндекс и тем более гугл сами по себе не юзают хромиум для этих целей?
      На сколько я понимаю одной из целей написания v8 у гугла как раз и было исполнение js при индексировании страниц, или как минимум это было бы логично
        +4
        Господа минусующие, прокомментируйте этот комментарий хотя бы для web-нубов?
        +1
        1. Поисковики выполняют JavaScript, но, насколько я понимаю, главная их проблема в этом случае — определение события окончания инициализации сайта.

        2. Для борьбы с этим и была придумана конструкция #!. Однако она не включает спец-режим рендеринга, а просто перенаправляет запрос на сервер в надежде получить уже скомпилированный исходник страницы по следующему правилу:
        localhost/#!/test-page --> localhost/?_escaped_fragment_=/test-page

        3. В добавок к этому, с увеличением поддержки HTML5 History API, люди переходят с #! на нормальную систему маршрутизации, что еще сильнее затрудняет задачу рендеринга страницы. Однако можно включить режим _escaped_fragment_ используя следующую конструкцию в шаблоне сайта:

        <meta name="fragment" content="!">
        
          0
          Резюмируя все сказанное — делать статические копии на данный момент необходимо для гарантии нормальной индексации.
            0
            Спасибо, очень интересно. Мне кажется вам стоит вынести ваш развёрнутый комментарий в пост, что бы обозначить проблематику, т.к. во-первых без него не совсем понятно зачем всё это надо и во-вторых, комментарий едва ли не интереснее самого поста
              0
              К сожалению у меня на это сейчас совсем нет времени.
              Плюс ко всему статьи на эту тему, насколько я помню, уже были на хабре.
                0
                Вы знаете, мне ещё интересен такой момент — когда мне считать свой сайт аяксовым? Т.е. требующим дополнительных манипуляций, как в статье. Если у меня js'ный фронтенд с rest'ом, то всё понятно, сайт аяксовый.
                А если у меня php+jquery, где два с половиной аяксовых запроса?
                  0
                  К сожалению, такой экспертизы у меня нет.
                  У меня либо статика либо full-ajax :-)
            0
            Так, к сведению: fragment ("#" и то, что после) на сервер не отправляется никогда, поэтому сервер в принципе не может знать, что нужно отрендерить или перенаправить #!/test-page.
              +1
              Это одна из причин существования спецификации escaped_fragment.
              +1
              Я вероятно что-то не так понимаю, но если бы я писал парсер сайтов для индексации — действовал как умный wget. То есть проходился бы по всем ссылкам и скачивал их содержимое рекурсивно.
              В случае, когда у меня в руках интерпретатор js — я бы еще исполнял js код перед «переходов» по ссылкам. В итоге опять вопрос — в чем сложность?
                +1
                Основная проблема, как я озвучил выше, в том, что нет точного события для определения того, что страничка отрендерилась полностью.
                Кроме разработчика этого сервиса наверняка это знать не может никто.
                  0
                  Ок. Хотя у вас в руках движок, который интерпритирует js, можно посмотреть что в стеке вызовов и тд и тп.
                  В посте не упоминается, что инструмент решает эту проблему и если я правильно понял, в коде инструмента эта проблема решена никак
                    0
                    Самый простой вариант, вы правы, это дождаться полного idle на странице.
                    В абсолютном большинстве случаев это сработает.
                    Но не во всех.
                    Поэтому эту проблему поисковики стараются делегировать на разработчиков.
                0
                Гугл умеет индексировать одностраничные сайты на JS (даже с History API), с проблемами пока не сталкивался. Пример — ost.io, полностью написанный на фреймворке Chaplin. Запрос site:ost.io в гугле находит 98 страниц. Сделайте $ curl -A Googlebot http://ost.io/@brunch/brunch и убедитесь, что сервер не отдает никакой отрендеренный html.
                С яндексом дела похуже — он пока не умеет.
                +1
                Я уже понял что на хабре принято минусовать, если у комментария уже есть минусы, но можно хоть свою точку зрения разъяснять?
                То, что описал KeepYourMind, никак не описано в посте и судя по коду инструмента никак не решается самим препендером
                  0
                  Решается как раз общий случай — ожидание полного рендера страницы и его отдача.
                  Единственное что он работает не по спецификации escaped_fragment, а эмулирует классический веб-сервис.
                    0
                    А вообще лучший вариант на данный момент — это рендер одновременно на сервере и клиенте.
                    см. derbyjs.com facebook.github.io/react/
                  0
                  Не применит ли гугл понижающие санкции для сайта использующего такой трюк? Т.к. эти действия сильно напоминают вот это support.google.com/webmasters/answer/66355
                  +2
                  Эм, простите, возможно я путаю кислое с солёным, но разве у гугла и бинга не используется особая магия для индексации аяксовых сайтов?
                  Где то даже на хабре была статья, что если в url'е присутствует /#!, то поисковик сразу понимает, что сайт аяксовый и использует специальные методики индексации.

                  Не могу сейчас найти ссылку на эту спецификацию, но для хотль какого то пруфа, оставлю здесь вот это:
                  www.yearofmoo.com/2012/11/angularjs-and-seo.html#how-google-and-bing-index-ajax-applications

                  Т.е. на самом деле не понятно — надо всё таки делать статические копии страниц, или нет.
                  +3
                  Пост похож на твиттер.
                    –1
                    А что еще писать нужно?
                    0
                    Как понимаю, если Prerender не успеет вовремя отрисовать страницу, то сайт получит «штрафные баллы» у ПС. Интересно, как быстро он работает.
                      0
                      Вы затронули интересный вопрос — а что там с перфомансом? Хотя что тут можно ответить? Как всегда без профайлера не разберёшься.
                      +2
                      Спасибо за пост, интересная штука, стоит глянуть на досуге.
                      Известная конструкция #! по сути не лучше чем Prerender, так что последний имеет право на жизнь. Причем если используя #!, мы отдаем индексацию на откуп поисковику и потом задаем вопросы типа «а вдруг гугл обработает как-то не так?», то prerender на первый взгляд позволяет решить вопрос самостоятельно и для любого поисковика.
                        0
                        Вот понимаете, проблема то в том, что если решение выглядит логичным, далеко не факт что оно работает. Я думаю библиотеку разрабатывают не совсем хипстеры и со своей задачей она справляется, но к ней есть ряд вопросов, которые при желании можно свести к двум: «А надо ли?» и «А оно точно работает?».

                        Если бы только можно было сравнить как-то пользу от библиотеки, до того как начнёшь внедрять её в проект.
                        0
                        Решение не лучшее. Подобных решений в последнее время появляется много, и в ходе обсуждений указывается один и тот же недостаток. А именно: рендеринг страниц с помощью PhantomJS занимает время. Фантом — штука неповоротливая, да и загрузка ресурсов большого приложения может занимать время. В результате ответ на запрос поискового бота приходит с большой задержкой. В свою очередь, некоторые поисковики (Google) снижают вес вашего контента в выдаче.

                        Пока что наиболее рекомендуемый вариант — это оставить нормальный статический контент в -тегах. Так, например, поступает Discourse. Сам клиент написан на EmberJS и использует HTML5 History API для навигации. Пользователи видят обычные урлы, которые могут постить где угодно. Но если по урлу приходит поисковый бот, то он видит контент внутри -тега. На сервере реализовано это довольно просто: ребята сели и написали простые темплейты, которые отображают текст для поисковика. По словам одного из разработчиков (слышал интервью в каком-то подкасте), заняла вся работа у них около недели. Поскольку Ember — url-driven фреймворк, то на каждый чих у ребят в приложении уже есть урл. Handlebars — не DOM-темплейты, а строковые темплейты, поэтому не требуют наличия какой-то исполняемой JS-среды на сервере: ни jsdom, ни Phantom, поэтому страница отдается браузеру быстро.
                          0
                          Заюзал пререндер в продакшене. Сайт в основном на бэкбон + ангулар частично. До этого вопрос решался через создание точных копий html страничек, которые надо скормить гуглоботу. Через недельку отпишу свои впечатления и расскажу что заиндексил гугл.
                            0
                            Ждем не дождемся )
                              0
                              В моей паралельной вселенной прошла неделька ))) В общем суммарно тк на сайте дохрилион страниц и некоторые выдают незначительный js ошибки — для пользователя страница грузится всеравно а вот фантом крэшится. Еще есть проблемка когда с дефолтными настройками пререндера страница не успевает отрендерится, добавил свои настройки в lib/server.js — увеличил таймаут — добавил ожидание спец строки на странице, сделал перенаправление напрямую к серверам(тк сейчас сайт находится за 2 сервисами которые ловят ботов и от ддоса защищают) всеравно переодически гугл получает в ответ недоделанную страницу(проверял с помощью Fetch as Google). Хоть даже с такими результатами странички индексятся — всеравно решили что надо искать другое решение. Выход нашел в построении вьюшки на стороне сервера, используя паршлы из js — получается неплохо за исключением того что надо учесть все роуты, которые идут после ?_escaped_fragment_=. Затестил часть страничек которые готовы — рендерятся все страницы корректно и быстро. Так что походу буду допиливать это решение и использовать на продакшне

                          Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                          Самое читаемое