Візуалізація на сервері ReactJS проти візуалізації на стороні клієнта


120

Я щойно почав вивчати ReactJS і виявив, що він дає вам два способи візуалізації сторінок: на серверній та клієнтській стороні. Але я не можу зрозуміти, як це використовувати разом. Це 2 окремі способи побудови програми, чи їх можна використовувати разом?

Якщо ми можемо використовувати це разом, як це зробити - чи потрібно дублювати однакові елементи на стороні сервера та клієнта? Або ми можемо просто побудувати статичні частини нашого додатку на сервері та динамічні частини на стороні клієнта без будь-якого з'єднання із стороною сервера, яка вже була попередньо надана?


1
Коротка відповідь, НІ - ви можете роз'єднати, надіслати статичний html та повністю змінити його у візуалізації клієнта. Додав деталі у свою відповідь.
Кіра

Відповіді:


108

Для даного веб-сайту / веб-додатку ви можете використовувати реакцію або на стороні клієнта , або на обох серверах .

Клієнтська сторона

Тут ви повністю запускаєте ReactJS у браузері. Це найпростіша установка і включає більшість прикладів (включаючи приклади на http://reactjs.org ). Початковий HTML, наданий сервером, є заповнювачем, а весь інтерфейс відображається у веб-переглядачі, коли всі ваші сценарії завантажуються.

На стороні сервера

Подумайте про ReactJS як механізм шаблону на стороні сервера (як нефрит, руль тощо). HTML, наданий сервером, містить інтерфейс користувача таким, яким він повинен бути, і ви не чекаєте завантаження будь-яких сценаріїв. Ваша сторінка може бути проіндексована пошуковою системою (якщо вона не виконує жодного JavaScript).

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

І те й інше

Тут початковий візуалізація знаходиться на сервері. Отже, HTML, отриманий браузером, має інтерфейс користувача таким, яким він повинен бути. Після завантаження сценаріїв віртуальний DOM знову рендерирується для настройки обробників подій ваших компонентів.

Тут вам потрібно переконатися, що ви повторно надаєте той самий віртуальний DOM (кореневий компонент ReactJS) з тим самим, propsякий ви використовували для візуалізації на сервері. В іншому випадку ReactJS поскаржиться, що віртуальні DOM на стороні сервера та клієнта не відповідають.

Оскільки ReactJS відрізняє віртуальні DOM між повторними рендерами, реальний DOM не мутується. Лише обробники подій пов'язані з реальними елементами DOM.


1
Тож у випадку "обох" мені потрібно написати один і той же код двічі "один для надання сервера, а один для відтворення цього DOM на клієнті? Так?"
Simcha

10
Вам потрібно запустити один і той же код двічі. Один раз на сервері та один раз на клієнті. Однак вам потрібно написати свої компоненти, щоб врахувати це - наприклад, ви не повинні робити жодних даних про асинхронізацію componentWillMount(), оскільки вони запускатимуть і клієнт, і сервер. Вам також знадобиться стратегія для отримання даних на фронті на сервері та надання їх для початкового візуалізації на клієнті, щоб переконатися, що ви отримаєте той самий вихід.
Jonny Buchanan

3
Ви також можете перевірити, чи виконується код на стороні сервера чи на клієнті, typeof window == "undefined"а потім отримати відповідні дані відповідно.
Гаутем Бадрінатан

Чи є у вас посилання на приклад, який відповідає вашій реалізації?
Sawtaytoes

1
@IanW Як правило, у цьому випадку HTML, повернутий сервером, є дуже "голими кістками", просто імпортуючи ваш JavaScript та стилі та містить <div>те, що React запише в.
Метт Холланд

48

Джерело зображення: Блог Walmart Labs Engineering

ССР

КСВ

Примітка: SSR (рендеринг на стороні сервера), CSR (надання клієнта на стороні).

Основна відмінність полягає в тому, що при SSR відповідь серверів на клієнтському браузері включає HTML сторінки, яку потрібно винести. Важливо також зазначити, що, маючи SSR, сторінка стає швидшою. Сторінка не буде готова до взаємодії з користувачем, поки файли JS не будуть завантажені та браузер не виконає React.

Одним із недоліків є те, що SSR TTFB (Час до першого байту) може бути трохи довше. Зрозуміло, що сервер потребує певного часу, створюючи HTML-документ, що, в свою чергу, збільшує розмір відповіді серверів.


4

Мені насправді цікаво було досліджувати те саме дослідження, і хоча відповідь, яку ви шукаєте, була дана в коментарях, але я вважаю, що вона повинна бути більш помітною, тому я пишу цей пост (який я оновлю, як тільки я зможу придумати кращий спосіб, оскільки я вважаю рішення архітектурно принаймні сумнівним).

Вам потрібно буде записати свої компоненти з урахуванням обох способів, таким чином, в основному, ставити ifкомутатори скрізь, щоб визначити, перебуваєте ви на клієнті чи сервері, а потім виконувати або як запит БД (або що завгодно на сервері) або виклик REST (на клієнт). Тоді вам доведеться записати кінцеві точки, які генерують ваші дані, і піддайте їх клієнту, і там ви вирушаєте.

Знову із задоволенням дізнаюся про більш чисте рішення.


2

Це 2 окремі способи побудови програми, чи їх можна використовувати разом?

Їх можна використовувати разом.

Якщо ми можемо використовувати це разом, як це зробити - чи потрібно дублювати однакові елементи на стороні сервера та клієнта? Або ми можемо просто побудувати статичні частини нашого додатку на сервері та динамічні частини на стороні клієнта без будь-якого з'єднання із стороною сервера, яка вже була попередньо надана?

Краще, щоб той самий макет виводився, щоб уникнути операцій поповнення та перефарбовування, менше мерехтіння / миготіння, ваша сторінка буде гладшою. Однак це не обмеження. Ви можете дуже добре кешувати html-код SSR (щось робить Electrode , щоб скоротити час відповіді) / надіслати статичний html, який буде перезаписаний CSR (рендерінг на стороні клієнта).

Якщо ви тільки починаєте з SSR, я рекомендую почати простий, SSR може отримати дуже складний дуже швидко. Побудувати html на сервері означає втрату доступу до таких об'єктів, як вікно, документ (у вас це є на клієнті), втрата можливості включити асинхронні операції (нестандартно) та, як правило, безліч редагувань коду, щоб ваш код був сумісний з SSR ( оскільки вам доведеться використовувати webpack для упаковки свого bundle.js). Такі речі, як імпорт CSS, вимагають від імпорту, раптом почніть кусати вас (це не так у програмі React за замовчуванням без веб-пакета).

Загальна схема ССР виглядає приблизно так. Експрес-сервер, що обслуговує запити:

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.