CSR, SSR, принцип Prerender полностью расшифрован

React.js

Передовые студенты, должно быть, слышали об этом более или менееCSR,SSR,PrerenderБольшинство этих существительных нужно только услышать, понять и немного понять, но действительно ли вы разбираетесь в этих технологиях?

Что именно означают эти существительные?

Почему возникла эта технология, и какую проблему предстоит решить?

В чем суть каждой технологии?

Начните с соответствующих концепций и процессов выполнения

Прежде чем понять эти концепции, мы должны сначала понять хорошо известную концепцию, т.SPA(Single Page Application)Да, это известное одностраничное приложение, на самом делеCSR、SSR、Prerenderоснованы наSPASPAЯ не буду подробно останавливаться на концепции.

CSR (рендеринг на стороне клиента)

То есть весь процесс рендеринга обрабатывается браузером, а сервер не участвует ни в каком рендеринге.

Упакованная страница выглядит так:

<body>
  <noscript>You need to enable JavaScript to run this app.</noscript>
  <div id="root"></div>
</body>
<script src="/static/js/2.22fca29f.chunk.js"></script>
<script src="/static/js/main.a9f5ef89.chunk.js"></script>

Процесс: браузер --> сервер --> index.html (белый экран) --> bundle.js --> изображения --> Рендеринг

image-20191231113956671

давайте использоватьcreate-react-appсоздатьwebмашиностроение, а вChromeиспользуется вslow 3GПроведите эксперимент в сети:

Xnip2019-12-29_17-49-12

Видно, что от пустого листа до прорисовки элемента прошло около 12 секунд, это ужасное время белого экрана, поэтому вWeb AppВ настоящее время размер пакета становится все больше и больше, что приводит к все большему и большему времени белого экрана.Все хотят оптимизировать причину этого явления.

Предварительный рендеринг (предварительный рендеринг)

То есть страница предварительно визуализируется, когда она упакована, поэтому, когда приходит запросindex.htmlуже отрендеренный контент

Процесс: браузер --> сервер --> index.html (предварительно обработанный контент) --> Рендеринг --> bundle.js + изображения --> Рендеринг

image-20191231113759430

Мы добавим проект прямо сейчасprerender-spa-pluginЭтот плагин, запустите его еще раз, чтобы увидеть результат

HTML-код упакованной домашней страницы выглядит следующим образом:

<body>
  <noscript>You need to enable JavaScript to run this app.</noscript>
  <div id="root">
    <div class="App">
      <header class="App-header">
        <img
          src="/static/media/logo.5d5d9eef.svg"
          class="App-logo"
          alt="logo"
        />
        <p>Edit <code>src/App.js</code> and save to reload.</p>
        <a
          class="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
          >Learn React</a
        >
      </header>
    </div>
  </div>
</body>
<script src="/static/js/2.22fca29f.chunk.js"></script>
<script src="/static/js/main.a9f5ef89.chunk.js"></script>

Домашняя страница уже предварительно обработана, поэтому давайте запустим ее еще раз, чтобы увидеть:

Xnip2019-12-30_13-54-09

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

SSR (рендеринг на стороне сервера)

Процесс: браузер --> сервер --> сервер выполняет рендеринг --> index.html (контент, отображаемый в реальном времени)) --> рендеринг --> bundle.js + изображения --> рендеринг

image-20191231111204363

видимыйSSRМы выполнили больше операций рендеринга в реальном времени на стороне сервера, так что же получилось на этот раз?

Xnip2019-12-31_11-17-55

Видно, что,SSRа такжеPrerenderЭффект тот же, и он может очень хорошо сократить время белого экрана.

Суммировать

Из вышеприведенных экспериментов видно, чтоSSRещеPrerender, проблема, которую мы хотим решить, в основном заключается в том, что время белого экрана слишком велико, эти две технологии должны решитьCSRВ чем разница между двумя схемами? Каковы сценарии использования?

P.S На самом деле другая причина в том, что,CSRправильноSEOЭто слишком недружественно. Поисковые системы не могут сканировать ключевую информацию. Они могут сканировать только пустую страницу без элементов, из-за чего поисковые системы не смогут найти информацию о вашей странице для получения рекомендации.SSRа такжеPrerenderможет очень хорошо решить эту проблему. (Тукао об этом:Googleуже реализовано сканирование на основеSPAизCSR)

Prerender or SSR

Прежде чем сделать выбор, мы должны полностью понять разницу между ними.

Prerender более общий, но слишком ограниченный

  1. PrerenderПринцип заключается в том, чтобы поставитьhtmlПосле рендеринга страницы она не будет ререндериться.То есть какая страница была при упаковке,тогда как выглядит пре-рендеринг.Если на странице есть данные которые обновляются в реале время браузер будет отображать его только при первой загрузке.Данные в это время не будут обновляться до тех пор, пока JS не будет загружен и отрендерен снова, что вызовет иллюзию задержки данных.

  2. PrerenderСтраницы для рендеринга должны быть указаны заранее, которые необходимо установить вручную в веб-пакете.

    new PrerenderSPAPlugin({
      staticDir: path.join(__dirname, "../", "build"),
      routes: ["/"]
    });
    

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

Сказав так много плюсов и минусов, как предварительный рендеринг генерирует страницы?

Студенты, которые делали рептилий, должны знать концепцию безголовых.

Безголовый Chrome был выпущен в Chrome59 для запуска браузера Chrome в безголовой среде, то есть для запуска Chrome в среде, отличной от Chrome. Он переносит все современные функции веб-платформы, предоставляемые механизмами рендеринга Chromium и Blink, в командную строку. Для чего это? Безголовый браузер — отличный инструмент для автоматизированного тестирования и серверных сред, где вам не нужна видимая оболочка пользовательского интерфейса. Например, протестируйте реальную веб-страницу, создайте PDF-файл веб-страницы или просто проверьте, как браузер отображает URL-адрес.

Prerenderэто использоватьChromeОфициально произведеноPuppeteerинструмент для сканирования страниц. Он предоставляет ряд API-интерфейсов, которые можно вызывать без пользовательского интерфейса.ChromeОн подходит для различных сценариев, таких как поисковый робот и автоматическая обработка. Он мощный, поэтому HTML-код времени выполнения легко упаковать в файл.

ПринципWebpackВ конце этапа сборки запустите локальныйPuppeteer, получить доступ к предварительно обработанному маршруту, а затемPuppeteerВизуализированная страница в выводе наHTMLфайл и создайте каталог, соответствующий маршруту.

Ниже приведена блок-схема

image-20191231143313360

SSR хорош, но нуждается в поддержке фреймворка

В настоящее время основная структураReact,Vueуже поддерживаютсяSSR, но конфигурация будет громоздкой, некоторых людей это смутит, а фреймворк должен поддерживатьSSR?

Но дело в том, что именно из-за современногоSPAизVirtual DOMСуществованиеSSRстать реальностью, однакоSSRРеализация этой идеи непроста.

Давайте посмотрим на деталиSSRблок-схема:

image-20191231172059262

Как можно заметить,SSRа такжеPrerenderСамая большая разница в том, что,Prerenderстатично,SSRдинамичный,SSRСоответствующий сервер будет построен в режиме реального времениDOM.

Это тожеSSRСложность заключается в: изоморфизме (то есть сервер и браузер построены вместе).

Что такое изоморфизм

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

Мы сказали выше,SSRв проекте,ReactКод выполняется один раз на стороне клиента и один раз на стороне сервера. Вы можете подумать, что в этом нет ничего плохого, это всеJavaScriptкод, который можно запускать как в браузере, так и вNodeбег в окружении. Но это не так, если вашReactВ коде есть прямая операцияDOMкод, то добиться невозможноSSRэту технологию, потому что вNodeокружающая среда, нет лиDOMКонцепция существует, поэтому эти коды находятся вNodeВ среде будет сообщено об ошибке.

Но из-заVirtual DOMСуществование технологий делает все это возможным, но я не буду вводить здесь слишком много.Virtual DOMкороче обычнаяJSобъект, только что нанесенный на картуHTML DOMСтруктура,ReactПри выполнении операций со страницами это на самом деле не прямая операцияDOM, но операцияVirtual DOM, то есть нормальная работаJavaScriptобъект, который делаетSSRстало возможным.

Мы можем напрямую судить о текущей рабочей среде в коде.Если это браузер, мы можем напрямую управлятьDOM, если это сервер, вам нужно использоватьVirtual DOMгенерироватьHTMLнить.

Вроде тут все очень просто, все идет по течению, но опять возникает проблема, что делать с роутингом

Маршрутизация браузера и маршрутизация сервера полностью два разных рабочих механизма.SPAМеханизм маршрутизации браузера можно увидетьздесь, на самом деле причина очень проста На стороне сервера нужно найти компонент маршрутизации через путь запроса, а на стороне клиента нужно найти компонент маршрутизации через URL в браузере, которых два совершенно разные механизмы, так что эта часть кода точно не публичная. .

такReactПредоставляется для браузера и сервера соответственноBrowserRouterа такжеStaticRouterдва маршрута черезBrowserRouterМы можем сопоставить компонент маршрутизации, который браузер собирается отобразить.Для браузера нам нужно преобразовать компонент вDOM, поэтому нам нужно использоватьReactDom.renderметод выполненияDOMустанавливать. а такжеStaticRouterОн может соответствовать компонентам, которые будут отображаться на стороне сервера.Для серверной стороны нам нужно преобразовать компоненты в строки.На данный момент нам нужно только вызватьReactDomкоторый предоставилrenderToStringметод, вы можете получитьAppкомпонент, соответствующийHTMLнить.

Ну, это почти сделано сейчас

Еще нет!

дляReactДля приложений маршрутизация обычно является точкой входа для выполнения всей программы. существуетSSR, маршрутизация на стороне сервера отличается от маршрутизации на стороне клиента, что означает, что код входа на стороне сервера и код входа на стороне клиента отличаются. Вход естьWebpackУпаковано завершено.

В соответствии с различной средой выполнения кода необходимо сделать разныеWebpackупаковка, нам нужноWebpackв конфигурацииtarget: 'node', что указывает на то, что среда сервера упакована.Кроме того, существуют различные конфигурации, которые необходимо решить.

подожди, на всякий случайReduxдля государственного управления

Если вы хотитеreduxДля глобального государственного управления вы должны помнить, чтобы написать его в этой форме:

const getStore = req => {
  return createStore(reducer, defaultState);
};
export default getStore;

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

Какие-либо заключительные моменты, чтобы отметить?

Так как у сервера нет жизненного цикла элементов монтирования, напримерReactизcomponentDidMountилиVUEизmountedЖизненный цикл не будет выполняться, поэтому, когда сервер использует интерфейс для получения данных, он не может быть записан в указанный выше жизненный цикл.

окончательное резюме

  1. Если на странице нет данных или это чисто статическая страница, рекомендуется использоватьPrerender, который представляет собой способ построения страницы путем предварительного просмотра пакета, и он не увеличит нагрузку на сервер, но в других случаях это не рекомендуется.
  2. Когда трафик слишком велик,SSRживых сборок активизируют серверCPUПотребление должно обрабатываться в сочетании с другими технологиями (такими как CDN, серверное кэширование, балансировка нагрузки и т. д.).
  3. Если есть много запросов данных страницы,SEOЕсли есть потребность в скорости загрузки, рекомендуется использоватьSSR
  4. Для проектов с высокими эксплуатационными требованиями,CSRможет быть более подходящим, элемент отображения страницы привязан к действию, иSSRа такжеPrerenderХотя страница будет отображаться заранее, элементы страницы в настоящее время не могут использоваться, и их все равно необходимо загрузить.bundle.jsПривязка события к выполнению

Конечно в реалеSSRВ процессе архитектуры трудность иногда представляет не идея реализации, а обработка деталей. Например, как установить разные настройки для разных страницtitleа такжеdescriptionУсиливатьSEOЭффект, на этот раз мы можем использоватьreact-helmetТакой инструмент помогает нам достичь наших целей, он отлично работает как для рендеринга на стороне клиента, так и для рендеринга на стороне сервера, и настоятельно рекомендуется. Есть также некоторые, такие как дизайн каталога проекта, обработка перенаправления 404, 301 и т. Д., Но эти проблемы нам нужно решать только одну за другой, когда мы сталкиваемся с ними на практике.