it-roy-ru.com

ReactJS рендеринг на стороне сервера против рендеринга на стороне клиента

Я только начал изучать ReactJS и обнаружил, что он дает вам 2 способа визуализации страниц: на стороне сервера и на стороне клиента. Но я не могу понять, как использовать это вместе. Это 2 отдельных способа создания приложения или их можно использовать вместе?

Если мы можем использовать это вместе, как это сделать - нужно ли нам дублировать одни и те же элементы на стороне сервера и на стороне клиента? Или мы можем просто построить статические части нашего приложения на сервере и динамические части на стороне клиента, без какого-либо подключения к стороне сервера, которое уже было предварительно обработано?

96
Simcha

Для данного веб-сайта/веб-приложения вы можете использовать реакцию на стороне клиента, на стороне сервера или оба.

Сторона клиента

Здесь вы полностью запускаете ReactJS в браузере. Это простейшая настройка и включает в себя большинство примеров (в том числе на http://reactjs.org ). Исходный HTML-код, отображаемый сервером, является заполнителем, а весь пользовательский интерфейс отображается в браузере после загрузки всех ваших сценариев.

Серверное

Думайте о ReactJS как о серверном шаблонизаторе (например, о нефрите, руле и т.д.). HTML-код, отображаемый сервером, содержит пользовательский интерфейс, как и должно быть, и вы не ожидаете загрузки скриптов. Ваша страница может быть проиндексирована поисковой системой (если не выполняется ни один javascript).

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

И то и другое

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

Здесь вам необходимо убедиться, что вы заново визуализируете тот же виртуальный DOM (корневой компонент ReactJS) с той же переменной props, которую вы использовали для визуализации на сервере. В противном случае ReactJS будет жаловаться, что виртуальные DOM на стороне сервера и на стороне клиента не совпадают.

Поскольку ReactJS различает виртуальные DOM между повторными рендерингами, реальный DOM не видоизменяется. Только обработчики событий связаны с реальными элементами DOM.

88
Gautham Badhrinathan

Источник изображения: Блог разработчиков Walmart Labs

 SSR

 CSR

NB: SSR (рендеринг на стороне сервера), CSR (рендеринг на стороне клиента).

Основное различие заключается в том, что в случае SSR ответ сервера на браузер клиентов включает HTML-код отображаемой страницы ........ Также важно отметить, что хотя при использовании SSR страница отображается быстрее. Страница не будет готова для взаимодействия с пользователем, пока файлы JS не будут загружены и браузер не выполнит React.

Недостатком является то, что SSR TTFB (время до первого байта) может быть немного длиннее. Понятно так, потому что серверу требуется некоторое время на создание HTML-документа, что, в свою очередь, увеличивает размер ответа сервера.

26
JSON C11

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

Вам нужно было бы написать свои компоненты с обоими способами таким образом, по сути, повсеместно помещая переключатели if, чтобы определить, находитесь ли вы на клиенте или на сервере, а затем выполняете либо как запрос к БД (или как угодно на сервере) или как REST вызов (на клиенте). Затем вам нужно будет написать конечные точки, которые генерируют ваши данные, и предоставить их клиенту, и все.

Опять же, рад узнать о более чистом решении.

3
SGD

Это 2 отдельных способа создания приложения или их можно использовать вместе?

Их можно использовать вместе.

Если мы можем использовать это вместе, как это сделать - нужно ли нам дублировать одни и те же элементы на стороне сервера и на стороне клиента? Или мы можем просто построить статические части нашего приложения на сервере и динамические части на стороне клиента, без подключения к серверу сторона, которая уже была предварительно обработана?

Лучше иметь тот же самый макет, который будет отображаться, чтобы избежать операций перекомпоновки и перекраски, меньше мерцания/миганий, ваша страница будет более гладкой. Тем не менее, это не ограничение. Вы могли бы очень хорошо кэшировать html SSR (что-то Electrode делает для сокращения времени отклика)/отправить статический html, который перезаписывается CSR (рендеринг на стороне клиента).

Если вы только начинаете с SSR, я бы порекомендовал начать с простого, SSR может очень быстро усложниться. Создание html на сервере означает потерю доступа к таким объектам, как окно, документ (у вас они есть на клиенте), потерю способности включать асинхронные операции (из коробки) и, как правило, множество изменений кода для обеспечения совместимости вашего кода с SSR ( так как вам придется использовать webpack для упаковки вашего bundle.js). Такие вещи, как импорт CSS, требуют, чтобы vs import внезапно начал кусаться (это не так в приложении React по умолчанию без веб-пакета).

Общая схема ССР выглядит следующим образом. Сервер Express, обслуживающий запросы:

const app = Express();
const port = 8092;

// This is fired every time the server side receives a request
app.use(handleRender);
function handleRender(req, res) {
    const fullUrl = req.protocol + '://' + req.get('Host') + req.originalUrl;
    console.log('fullUrl: ', fullUrl);
    console.log('req.url: ', req.url);

    // Create a new Redux store instance
    const store = createStore(reducerFn);

    const urlToRender = req.url;
    // Render the component to a string
    const html = renderToString(
        <Provider store={store}>
            <StaticRouter location={urlToRender} context={{}}>
                {routes}
            </StaticRouter>
        </Provider>
    );
    const helmet = Helmet.renderStatic();

    // Grab the initial state from our Redux store
    const preloadedState = store.getState();

    // Send the rendered page back to the client
    res.send(renderFullPage(helmet, html, preloadedState));
}

Моим предложением для людей, начинающих с SSR, было бы предоставить статический HTML. Вы можете получить статический HTML, запустив приложение CSR SPA:

document.getElementById('root').innerHTML

Не забывайте, что единственными причинами использования SSR должны быть:

  1. SEO
  2. Более быстрые нагрузки (я бы обесценил это)

Взломать: https://medium.com/@gagan_goku/react-and-server-side-rendering-ssr-444d8c48abfc

0
Kira