Привет, Хабр! Все знают что для того, чтобы ваш сайт увидели поисковые роботы вам нужен SSR. Но единственное ли это решение? Всегда ли он нужен? Есть ли другие варианты роботам увидеть контент? Что мы можем выиграть от альтернатив?

В этой статье рассмотрим альтернативное решение для SSR, а именно Динамический рендеринг (он же Пререндеринг).

* SSR имеется ввиду с регидрацией.

Какую проблему мы решаем?

Есть два способа генерации контента веб сайта:

  • Серверный - генерируется программой на стороне сервера. Для генерации такого контента на стороне сервера должна работать ваша программа.

  • Клиентский - генерируется скриптом на стороне браузера. Для генерации такого контента на стороне сервера программа не нужна, достаточно сервера статики.

На самом деле есть еще 4 смешанных варианта, но о них позже.

Оба метода имеют свои плюсы и минусы. Большой минус серверного рендеринга заключается в том что веб сайт получается "не живой". В нем мало интерактивных элементов, переход по страницам крайне неприятен и занимает много времени. Но такой контент видят поисковые роботы. Большой минус клиентского рендеринга это отсутствие видимости для роботов. Роботы такой контент просто не видят. Только недавно Гугл и Яндекс научились видеть такой контент, но скорость такой индексации оставляет желать лучшего. Но зато такой веб сайт "живой". В нем много интерактивных элементов и переходы по страницам мгновенны для пользователя.

SSR является компромиссным вариантом и объединяет в себе подходы серверного и клиентского рендеринга. Он с начало рендерит страницу на сервере, потом оживляет ее при рендеринге на клиенте. Таким образом поисковые роботы видят контент, а клиенты получают живой и интерактивный сайт.

Но помимо плюсов у данного подхода есть и минусы. И далее мы сравним плюсы и минусы подходов Пререндеринга и SSR.

Что такое Пререндеринг?

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

Для пререндера вам понадобится вспомогательная программа работающая на стороне сервера независимо от вашего веб сайта. На стороне прокси сервера вашего сайта делается настройка, которая разделяет пути следования клиентов и поисковых роботов. Клиентам отдается статичный сайт с клиентским рендерингом. Роботы отправляются на программу пререндеринга. Программа пререндеринга открывает сайт, дожидается его загрузки и отправляет результат открытого сайта поисковому роботу. Фактически это то же самое чем занимаются пререндеры поисковых роботов, только мы это реализуем на своей стороне, чтобы помочь роботам лучше индексировать контент своего сайта.

Детальнее про пререндеринг можно почитать в документации гугла. Я для обзора буду рассматривать микросервис пререндеринга от компании МТС который называется BotView. Так же есть сервис prerender.io который предоставляет услуги пререндеринга и открытый контейнер для пререндеринга. Но его мы рассматривать не будем так как он менее стабильный, менее быстрый и менее функциональный чем BotView.

Как настроить пререндер?

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

docker run -d --restart always -p 3000:3000 mtsrus/botview

Во-вторых, на прокси сервере необходимо настроить разделение путей для реальных клиентов и поисковых роботов. Чтобы реальным клиентам отдавались статичные файлы, а поисковые роботы перенаправлялись на пререндер.

location / {

    set $prerender 0;

    # all popular bots
    if ($http_user_agent ~* "googlebot|facebookexternalhit|twitterbot|telegrambot|yahoo|bingbot|baiduspider|yandex|yeti|yodaobot|gigabot|ia_archiver|developers\.google\.com") {
        set $prerender 1;
    }

    # bot with escape fragments
    if ($args ~ "_escaped_fragment_") {
        set $prerender 1;
    }

    # prerender microservice
    if ($http_user_agent ~ "Prerender") {
        set $prerender 0;
    }

    # static files
    if ($uri ~ \.[a-zA-Z0-9]+$) {
        set $prerender 0;
    }

    if ($prerender = 1) {
        rewrite (.*) /render/$scheme://$host$1?prerender break;
        proxy_pass http://localhost:3000;
    }

    if ($prerender = 0) {
        proxy_pass http://localhost:8080;
    }
}

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

Как будем сравнивать?

Для сравнения возьмем две популярные технологии разработки сайтов. Сайт реализованный как статичные файлы и сайт реализованный на Next.js с SSR. И пройдемся по наиболее интересным вопросам использования.

Стоимость хостинга

Когда вы хостите сайт как статичные файлы вам достаточного самого дешевого хостинга. Потому что такие сайты не потребляют серверные ресурсы. Достаточно несколько гигабайт диска, немножко процессора, немножко памяти и немножко сети. Далее для рендеринга кода сайта будут использованы ресурсы клиентских устройств, за которые вам платить не надо.

Когда вы хостите сайт как программу с SSR, то на сервере вам понадобится много ресурсов для вашей программы. Потому что теперь для рендеринга сайта будут использоваться серверные ресурсы и много. Понадобится много процессора, много памяти, много сети. Кроме того вырастет нагрузка на сеть, ведь отрендереную серверную страницу нельзя кэшировать. Но самое забавное, что клиент все равно будет рендерить, то же самое. Переложив рендеринг на сервер вы не на чем не сэкономили, вы лишь заплатили за поддержку поисковых роботов.

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

Но на самом деле у SSR тоже есть козыри. Например, если брать фреймворк Next.js то он может работать не только как SSR решение, но и как SSG, и как SSG + SSR решение. Таким образом страницы могут генерироваться как статичные на этапе сборки или в рантайме по интервалу с новыми данными. Таким образом фреймворк позволяет снизить нагрузку на сервер и клиентам выдавать кэшированные данные.

Но за пререндер на сервере тоже надо платить? Да. Но робот приходит на страницу 1 раз в 2 недели. Это гораздо меньше чем обычно клиентов приходят на вашу страницу.

Победитель: Пререндер.

Надежность

Когда вы хостите сайт как статичные сайты то ваш сайт фактически бессмертен. Это самый простой вид хостинга, его невозможно ни взломать ни сломать. В худшем случае произойдет DDOS и у вас откажет сетевое оборудование, но сайт продолжит работать.

Когда вы хостите сайт как серверную программу то у вас появляется множество проблем по поддержанию работоспособности данной программы. Что бы она не зависла, не сломалась, нагрузка находилась в пределах нормы, что бы программу нельзя было взломать и захватить сервер. Скорее всего вам придется подключить мониторинг и метрики. Кроме того большое количество клиентов могут заставить вашу программу потреблять больше ресурсов чем есть на сервере и тогда программа сломается.

Победитель: Пререндер.

Стоимость разработки

Когда вы разрабатываете для SSR вам необходимо разрабатывать сразу под две платформы Браузер и NodeJS. Эти платформы имеют разное API. В частности на стороне NodeJS отсутствуют такие объекты как window, location, screen и многие другие. Из-за чего часто приходиться выкручиваться создавая логику без использования этих объектов или вовсе оставляя заглушку для обработки на стороне клиента. Например частенько при разработке под SSR нужно знать размер экрана пользователя, но вы его никак не можете знать на стороне сервера, поэтому вы рендерите заглушку, потом код передается на клиент где уже происходит более полноценный расчет логики и перерендеринг уже с реальными данными. Все эти нюансы увеличивают стоимость разработки.

Когда вы разрабатываете под Пререндер вы разрабатываете только под браузер. Где есть все необходимое для написания логики.

Победитель: Пререндер.

Поддержка технологий

Когда вы используете SSR вы сильно ограничены в используемых технологиях. Next.js только два месяца назад научился безболезненно работать с динамическими данными. В других фреймворках работать с динамическими данными все еще проблемно или невозможно вовсе. На стороне SSR вы не можете использовать множество браузерных фич, таких как Веб компоненты, Микрофронтенды, Фреймворки и пр.

Пререндеринг выполняется в полноценном браузере, поэтому вам доступны все те технологии которые есть браузере без ограничений. Вы не ограничены в библиотеках и фреймворках. Вы можете использовать его для чего угодно, включая JQuery, AngularJS, Angular, Vue, SolidJS и др.

Победитель: Пререндер.

Хайп и комьюнити

SSR в настоящий момент является основным и рекомендуемым Гуглом. По данному подходу можно найти огромное количество статей и документации. Все современные фреймворки обладают функцией рендеринга через SSR.

Пререндер удел интузиастов. Он перестал быть основным инструментом поставки контента поисковым роботам, так же перестал быть рекомендованным инструментом Гугл.

Победитель: SSR.

Функциональность

Когда вы разрабатываете с SSR вам приходиться хостить на сервере программу. При таком подходе у вас появляется возможность разместить в программе не только клиентский код, но и API, и код бекенда. Таким образом вы можете принимать запросы от клиента, делать рассылки и исполнять любую необходимую бизнес логику. Фактически вы превращаетесь в фуллстек разработчика.

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

Победитель: SSR.

Какое из решений является костылем?

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

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

Что выбрать вам?

Решать вам. Я выбираю в зависимости от задачи проекта.

Свои личные проекты я реализую как статичные сайты с пререндером. Потому что так стоимость хостинга значительно ниже и не надо заморачиваться с надежностью.

На работе решение выбирается в зависимости от задачи. Где то это статика с пререндером, где то это фулстек проект на Next.js. Но в подавляющем большинстве это все же Next.js с SSG + SSR.

С другой стороны если ваш фреймворк не поддерживает SSR, например это JQuery или старый Angular, то Пререндер это ваш единственный вариант, при котором контент будет доступен поисковым роботам.

Комментарии (19)


  1. LuggerFormas
    13.01.2023 12:32
    +2

    Это невозможно читать


    1. LabEG Автор
      13.01.2023 13:50
      -2

      Родной для меня C#, русским владею только с Вордом. Лицензия на который кончилась, и продлить невозможно. Если знаете хороший сервис проверки грамматики посоветуйте пожалуйста. Спасибо за правки, где понял какая ошибка поправил.


      1. IRS
        13.01.2023 14:53

        Apple pаges могет в грамотность. Если же линукс то есть ispell


  1. mobi
    13.01.2023 13:12

    А за cloaking разве не пессимизируют в выдаче?


    1. LabEG Автор
      13.01.2023 13:58

      Пессимизируют если контент отличается. Например, на сервере вы выдаете контент про здоровое питание, а скриптом подменяете на контент про что-то нелегальное. Когда контент одинаковый то роботы воспринимают его правильно. Кроме того у того же гугла пререндер недавно был рекомендуемым инструментом. И на личной практике он успешно справляется и сайты на пререндере находятся в топе по нужным ключевым словам.


  1. Shado_vi
    13.01.2023 14:05
    +1

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


    1. LabEG Автор
      13.01.2023 14:15
      -1

      Статья про то как роботам увидеть весь контент. Вариант с минимальной частью на сервере ближе к клиентскому рендерингу. Гугл и яндекс научились рендерить такие сайты, но у гугла результат совсем плохой, у яндекса совсем недавно появилось поэтому статистики еще нет. Остальные роботы зависит от поддержки клиентского рендеринга.


  1. strokoff
    14.01.2023 11:12

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


    1. LabEG Автор
      14.01.2023 12:57

      На клиентах он действительно не нужен, т.к. на клиенте в любом случае придётся рендерить чтобы оживить сайт. И получается что к времени клиентского рендеринга добавляется еще время серверного рендеринга и передачи серверной страницы на клиент. Т.е. клиент от этого только проигрывает как по объему трафика, так и по времени ожидания. Где то в англоязычных интернетах про это даже хорошая статья есть с цифрами и графиками. Да и на моих проектах я не могу получить 500 балов по ligthouse через SSR из-за лишнего трафика и времени, на клиентском рендеринге 500 балов получается элементарно.

      Поэтому все фреймворки с SSR работают по следующему принципу. При обращению к первой странице происходит SSR, при последующих страницах работает исключительно клиентский рендеринг. А боты не умеют в переходы, поэтому они запрашивают следующую страницу.

      А про трудности слабых устройств вы сильно преувеличили, даже бюджетного 10 летнего телефона хватит что бы без проблем отрендерить сайт на стороне клиента. Главное использовать легковесные библиотеки и фреймворки. Но основная проблема на таких устройствах не скорость рендеринга JS, а скорость обработки CSS. Слабые устройства заставляют тормозить сложные CSS.


      1. strokoff
        14.01.2023 13:11

        рендерить чтобы оживить

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

        добавляется время серверного рендеринга

        Что если сервер отвечает и так в районе 100-200ms тк мощности сервера несравнимо больше чем у среднестатистического телефона. Получается добавляется время клиентского рендера, ответ от сервера вам в любом случае предстоит подождать. Стоит ли оно того и нужно ли вообще поверх гидрировать сайт в интерактивный? Метрики Total Block Time и Time to Interactive вам о чем говорят, как вы оптимизируете их на проекте?

        Главное использовать легковесные библиотеки и фреймворки.

        Тогда vue, react, angular идут на помойку? они не легковесные

        Легковесные это alpine.js его аналог petite-vue, оба работают на уже отрисванном DOM и проповедуют Progressive Enhancement который в свою очередь проповедует следующее тезисы:

        • Basic content should be accessible to all web browsers

        • Basic functionality should be accessible to all web browsers

        Под all browsers понимаются не только современные браузеры, но в целом ВСЕ браузеры отображающие HTML, ваш поход не подразумевает доступность сайта для всех браузеров, только для хедлайнеров. Например читать SPA через eink читалку уже невозможно, хотя может такие пользователи вам просто не нужны? Я ни на что не претендую и нивкоем случае не принижаю вашу статью, просто хочется напомнить, что в 2023 сайты живут не только как SPA и SSR приложения, классический подход к сайтостроению никуда не ушел (популярность CMS Wordpress\Joomla тому подтверждение, а в фреймворках типа Symfony\Laravel можно использовать очень мощный Twig шаблонизатор, такой подход поныне актуален, хотелось бы чтобы и в статье об этом было хоть чуточку упоминаний.


        1. LabEG Автор
          14.01.2023 18:55
          +1

          Где вы вообще нашли функцию выключения JS в 2023 году? ))
          Вы недооцениваете хабру. Если посмотреть профайлер инициализации хабры, то у нее скриптов не меньше чем в любом навороченном сайте. Карму вы не поднимете, комментарий не напишите, элементарно три точки под комментом работать не будут, я уж молчу про аналитику и рекламу. Если вам нужен текст без JS вы можете прочитать в другом формате, например RSS. Но нет, вы открыли не RSS, а JS и жалуетесь на то что здесь работает JS. Это был ваш выбор, а не чей то другой. Выбирали бы RSS было бы больше контента на RSS.

          Вы почему то думаете 1 сервер обслуживает только 1 клиента. Но это не так. Один сервер обслуживает сотни и тысячи клиентов в секунду. Если взять бюджетный телефон, например Redmi 9 за 9 тысяч и новый Xeon за 200 тысяч, да, Xeon будет в 100 раз быстрее, но обслуживать будет 1000 клиентов. При таком раскладе на одного клиента придётся в 10 раз меньше ресурсов. Уже писал в статье что делал программу на клиентском рендеринге и она занимала всего 10% от 4 ядер, в то время как аналогичная программа с серверным рендерингом занимала 15 навороченных серверов. Которые еще и поддерживать надо. И метрики TBT и TTI у клиентского рендеринга лучше за счет отсутствия двойной работы по серверному и клиентскому рендерингу.

          vue, react, angular - да, на помойку. Как минимум надо использовать preact, svelte, solidjs (на худой конец $mol ;) ).

          alpine.js - выдает вам шаблон который все равно рендерится на клиентской стороне. Вы не сможете прочитать статьи выведенные в циклы в alpine.js пока их не обработает JS. Это все го лишь другой шаблонизатор. Кроме того по тестам перформанса он в разы медленее не только preact, но и react. Пруф по ссылке.

          Да, я когда делаю софт делаю поддержку не всех браузеров, а только тех чья доля составляет более 0,5% на рынке. Понижать эту планку экономически не целесообразно, т.к. такая поддержка не то что никогда не окупится, но и принесет ущерб самым массовым клиентам. Если бы клиенты хотели бы видеть контент без JS они бы выбирали RSS, Markdown и другие статичные форматы. Но именно клиенты выбирают JS.

          Ну и php мертв, очень странно легаси считать актуальным стеком.


          1. strokoff
            14.01.2023 19:21

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

            Ну и php мертв, очень странно легаси считать актуальным стстекомн

            Я пока не готов утверждать, что php мертв, как и сайты на symfony/laravel joomla/wp это мертвое Легаси в коде, попробуйте в телеграмм каналах сообществ сообщить людям о мертвом php


            1. LabEG Автор
              15.01.2023 10:28

              Почему форма именно на JS:

              1. Обратите внимание, редактор комментариев это не просто текстовый элемент, а довольно таки сложный редактор со сложным функционалом. Без JS такое работать не будет.

              2. Эта форма отправляет на бекенд не то что вы видите и не html. Эта форма отправляет на бекенд JSON. Это нужно для того чтобы потом можно было отобразить те же комментарии в нативном приложении.

              3. Форма на submit вызовет мерцание страницы с потерей положения скрола + лишним трафиком на повторную загрузку статьи. Форма на JS красиво вставляет комментарий в список комментариев, без каких либо мерцаний и перезагрузок страниц. Если любому человеку предложить два варианта поведения, то он выберет форму без мерцания и потерей скрола.

              Ходить по телеграмм каналам и теребить чувства верующих не в моих правилах. Но сами наверное понимаете что рендерить страницу на html и оживлять через jquery в 2023 может только совсем не адекватный человек. Куда проще взять Next.js и написать изоморфное приложение.


        1. LabEG Автор
          15.01.2023 15:20

          Кстати про читалку.

          Этот сайт выполнен как клиентский рендеринг и напичкан JS буквально в каждом элементе. При этом он отлично себя чувствует на читалке. Секрет в легковесных библиотеках и стейт менеджере.

          Кроме того использован эффект одного TCP пакета. В нем расположен лоадер. За счет чего на читалке почти сразу отобразился лоадер и еще секунд 10 шла загрузка.

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


          1. strokoff
            15.01.2023 16:15

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


            1. LabEG Автор
              15.01.2023 16:42

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


              1. strokoff
                15.01.2023 17:10

                Опять фиаско, может вам сервер получше арендовать? 10сек на одного клиента это треш, у нас даже самые большие выборки в бд на проекте с 12млн аудиторией не работают так медленно, как всего 1 ваш шаблонизатор. Впрочем с ваших слов у нас мертвый стек (микросервисы на симфони в кубер кластере) и фронт на vue ssr без всяких nuxt/next


                1. LabEG Автор
                  15.01.2023 18:20

                  Вы так и не поняли. Это не время отрабатывания сервера. Это время отрисовки устройства. Очень медленно парсится страница и рендерится CSS.


                  1. strokoff
                    15.01.2023 18:26

                    вариант с серверным рендерингом грузился дольше чем вариант с клиентским рендерингом и вызвал ощущение зависшего сайта.

                    Так сервер в итоге работал медленнее клиента или нет? Как вы измерили, что например именно формирование CSSOM на клиенте сожрало основное время загрузки? Но это вроде чисто клиентская история и CSSOM на сервере не генерируется, там просто стили инклудятся в разметку