Когда сложность клиентской стороны сайта становится или предполагается высокой, на помощь приходят библиотеки для построения интерфейса. Они делают разработку динамического интерфейса проще, а также упрощают сопровождение кода, так как каждый фреймворк диктует свой подход к организации кода. К таким библиотекам относят 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
Если у тебя есть желание попробовать самому, инструкция по сборке и запуску есть в репозитории.