Не серверный рендеринг, но все равно хотите ускорить производительность вашего сайта React? Попробуйте предварительный рендеринг!
react-snap
— сторонняя библиотека, которая предварительно визуализирует страницы вашего сайта в статические файлы HTML. Это может улучшить время первой отрисовки в вашем приложении.
Вот сравнение одного и того же приложения с предварительной обработкой и без нее, загруженного на имитируемое 3G-соединение и мобильное устройство:

Почему это полезно?
Основная проблема производительности больших одностраничных приложений заключается в том, что пользователю необходимо дождаться завершения загрузки пакета(ов) JavaScript, из которых состоит сайт, прежде чем он сможет увидеть какой-либо реальный контент. Чем больше пакеты, тем дольше пользователю придется ждать.
Чтобы решить эту проблему, многие разработчики используют подход рендеринга приложения на сервере вместо того, чтобы загружать его только в браузере. При каждом переходе страницы/маршрута полный HTML генерируется на сервере и отправляется в браузер, что сокращает время первой отрисовки, но приводит к более медленному времени до первого байта.
Предварительный рендеринг — это отдельная техника, которая менее сложна, чем серверный рендеринг, но также позволяет улучшить время первой отрисовки в вашем приложении. Headless-браузер или браузер без пользовательского интерфейса используется для генерации статических HTML-файлов каждого маршрута во время сборки . Затем эти файлы можно отправлять вместе с пакетами JavaScript, необходимыми для приложения.
реагировать-щелкать
react-snap
использует Puppeteer для создания предварительно отрендеренных HTML-файлов различных маршрутов в вашем приложении. Для начала установите его как зависимость разработки:
npm install --save-dev react-snap
Затем добавьте скрипт postbuild
в ваш package.json
:
"scripts": {
//...
"postbuild": "react-snap"
}
Это автоматически запускало бы команду react-snap
каждый раз при создании новой сборки приложений ( npm build
).
Последнее, что вам нужно сделать, это изменить способ загрузки приложения. Измените файл src/index.js
на следующее:
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
ReactDOM.render(<App />, document.getElementById('root'));
const rootElement = document.getElementById("root");
if (rootElement.hasChildNodes()) {
ReactDOM.hydrate(<App />, rootElement);
} else {
ReactDOM.render(<App />, rootElement);
}
Вместо того, чтобы использовать ReactDOM.render
только для рендеринга корневого элемента React непосредственно в DOM, он проверяет, присутствуют ли уже какие-либо дочерние узлы, чтобы определить, было ли содержимое HTML предварительно отрендерено (или отрендерено на сервере). Если это так, то вместо этого используется ReactDOM.hydrate
для присоединения прослушивателей событий к уже созданному HTML вместо его создания заново.
Сборка приложения теперь будет генерировать статические файлы HTML в качестве полезных нагрузок для каждого маршрута, который сканируется. Вы можете посмотреть, как выглядит полезная нагрузка HTML, нажав URL-адрес HTML-запроса, а затем нажав вкладку Previews в Chrome DevTools.
Вспышка нестилизованного контента
Хотя статический HTML теперь отображается почти немедленно, он по-прежнему остается нестилизованным по умолчанию, что может вызвать проблему отображения "вспышки нестилизованного контента" (FOUC). Это может быть особенно заметно, если вы используете библиотеку CSS-in-JS для генерации селекторов, поскольку пакет JavaScript должен будет завершить выполнение, прежде чем можно будет применить какие-либо стили.
Чтобы предотвратить это, критический CSS или минимальный объем CSS, необходимый для отображения начальной страницы, можно встроить непосредственно в <head>
HTML-документа. react-snap
использует другую стороннюю библиотеку под капотом, minimalcss
, для извлечения любого критического CSS для различных маршрутов. Вы можете включить это, указав следующее в вашем файле package.json
:
"reactSnap": {
"inlineCss": true
}
При просмотре предварительного просмотра ответа в Chrome DevTools теперь будет отображаться стилизованная страница с критически важным встроенным CSS.
Заключение
Если в вашем приложении нет маршрутов рендеринга на стороне сервера, используйте react-snap
для предварительной отрисовки статического HTML для ваших пользователей.
- Установите его как зависимость разработки и начните с настроек по умолчанию.
- Используйте экспериментальную опцию
inlineCss
для встраивания критически важного CSS, если она подходит для вашего сайта. - Если вы используете разделение кода на уровне компонентов в любых маршрутах, будьте осторожны, чтобы не делать предварительную визуализацию состояния загрузки для ваших пользователей. README
react-snap
описывает это более подробно.