Привет, я Михаил.
Работаю веб-разработчиком и занимаюсь интернет-проектами: от сайтов и интерфейсов до систем автоматизации.
Связаться со мной

Серверный рендеринг: React, Redux, PHP

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

Почти год я использую React на реальных проектах: интерфейс системы автоматизации, личный кабинет клиента на сайте и так далее. Обычно части проекта, разработанные таким образом, не предназначены для индексации поисковыми системами. К тому же, при таком подходе весь интерфейс генерируется на клиенте, а не на сервере, как это традиционно делается практически на каждом сайте. Последнее часто вызывает вопросы у SEO-специалистов, так как не ясно, как поисковые системы отнесутся к тому, что в HTML-коде, который отдаётся сервером, не содержится ничего кроме скелета HTML-страницы и подключения скриптов.

Насколько известно, Яндекс и Google адекватно относятся к такому содержимому. Тем не менее, тема серверного рендеринга остаётся актуальной до тех пор, пока мифы о плохой индексации динамического содержимого не развеются.

Так вот, когда сайт сложный, разумно использовать библиотеку для построения интерфейса. Чтобы сервер кроме голой страницы отдавал ещё и ту вёрстку, которую получает в итоге клиент, разработчики прибегают к серверному рендерингу. Обычно всё сводится к тому, что на сервере исполняется JavaScript-код с помощью JavaScript-движка, наиболее популярный — V8.

Несмотря на то, что 90% кода, написанного мной за последние полгода — это JavaScript, я не воспринимаю этот язык как серверный. Поэтому мой выбор пал на рендеринг React-компонентов с помощью PHP. Для этого я установил PHP-расширение v8js и написал простой проект на React с использованием Redux. Это даже не банальный TODO, мне был интересен сам принцип работы.

Вот пример скрипта на PHP. Здесь подключается библиотека V8Js, которая рендерит React-приложение, а результат вставляется в итоговый HTML-код. Да, старая добрая классика: PHP, HTML и JavaScript в одном файле. Не хватает только запросов на SQL.

<?php
$isServerRenderingEnabled = true;
$markup = '';
if ($isServerRenderingEnabled) {
    require_once dirname(__FILE__) . '/vendor/autoload.php';

    function getMarkup($component, $props) {
      $default_prop = json_encode($props);
      $v8 = new V8Js();
      $js[] = "var global = global || this, self = self || this, window = window || this;";
      $js[] = file_get_contents('./front/dist/bundle.js', true);
      $js[] = "print(ReactDomServer.renderToString(React.createElement(${component}, ${default_prop})));";
      $code = implode(";\n", $js);
      ob_start();
      $v8->executeString($code);
      return ob_get_clean();
    }

    $component = 'App';
    $props = [];
    $markup = getMarkup($component, $props);
}
?>

<!DOCTYPE html>
<html>
  <head>
    <title>SSSR Simple</title>
  </head>
  <body>
    <div id="app"><?php echo $markup;?></div>
    <script src="front/dist/bundle.js"></script>

    <script>
        document.onreadystatechange = function () {
          if (document.readyState === 'complete') {
            ReactDom.render(
              React.createElement(App, {}),
              document.getElementById('app')
            );
          }
        }
    </script>
  </body>
</html>

Весь код можно увидеть в моём репозитории на GitHub.

С использованием Redux: https://github.com/mishantrop/sssr

Без использования Redux: https://github.com/mishantrop/sssr/tree/simple

Если у тебя есть желание попробовать самому, инструкция по сборке и запуску есть в репозитории.