Использование prerender-spa-plugin для улучшения работы одностраничных приложений

задняя часть внешний интерфейс GitHub Vue.js

Автор: Ван Нань

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

Нужно прописать не только функции и экологию фреймворка, конечно, нельзя забывать о принципе «user first» и опыте заклинаний. Неутомимые фронтенд-друзья дали несколько решений: 1. Рендеринг на стороне сервера (SSR), 2. Пререндеринг. Ниже я представлю их один за другим.

Что такое ССР?

Дословный перевод SSR - это рендеринг на стороне сервера, путем установкиSSR, Вы сможетеNode.jsЛогика рендеринга завершается в среде, а затемHTMLПредставления возвращаются непосредственно клиенту. Таким образом, вы можете не только использоватьVueа такжеReactтехнологии и может напрямую выводить содержимое страницы. Вместо того, чтобы просто иметь пустую оболочку на заднем конце. Это также облегчает роботам поисковых систем получение страниц, решаяSEOвопрос.

Что не так с ССР?

Вы можете вспомнить нашу фронтенд-модель разработки давным-давно, по сути, бэкенд прямо из страницы. Внешний интерфейс реконструирует страницу, а внутренний набор страниц отображает данные домашней страницы. Конечно, некоторые асинхронные данные передаются черезajaxПолучить визуализацию данных. Похоже, это возврат к предыдущей модели развития. Front-end и back-end по-прежнему тесно связаны. Неудобство обслуживания и итерации.

Так это не хорошо? немного! В настоящее время в обществе все еще существуют зрелые фреймворки и онлайн-продукты, такие какNuxt.js[1],

 

, Что это все еще имеет ценность. Очевидно, что это может решить такие проблемы, как белый экран в верхней части страницы или SEO. Однако он также создает много проблем: во-первых, он предъявляет высокие требования к инженерам и требует знания как фронтенда, так и бэкенда. Во-вторых, рассмотрим серверную частьNode.jsУтечки памяти, скорость работы, давление параллелизма и другие проблемы в среде.NodeУслуги уровня можно охарактеризовать как «хрупкие». В-третьих, стоимость разработки увеличивается, а цикл исследований и разработок становится длиннее. Вообще говоря, для поддержки нагрузки на сервер требуется сильная и стабильная инфраструктура.

Если вы можете справиться с этим, без сомненияSSRЭто отлично подходит для улучшения работы с приложением~, но для тех, кто немного беспокоится, как я, есть ли какое-либо другое решение? немного,Prerendering!

Prerendering

Иногда одностраничное приложение, которое мы разрабатываем, состоит всего из нескольких страниц, очень маленьких, только для целейSEO, Проблема с белым экраном на главной странице, все думают, что она немного исправлена. Доступны сторонние плагиныprerender-spa-plugin[2], для реализации рендеринга на стороне клиента, чтобы не было необходимостиVueилиReactКод развертывается на стороне сервера.prerender-spa-pluginдаWebpackПлагин, он может скомпилировать все статические страницы в приложении и легко установить соответствующий индексный путь. Объединить нижеVue.jsа такжеprerender-spa-pluginдля решения вышеупомянутых проблем.

Установить

 npm install prerender-spa-plugin --save-dev

использовать

const PrerenderSPAPlugin = require('prerender-spa-plugin');
const Renderer = PrerenderSPAPlugin.PuppeteerRenderer;

module.exports = {
plugins: [
 new PrerenderSPAPlugin({
      staticDir: path.join(__dirname, 'dist'),
      routes: [ '/', '/about', '/contact' ],
      renderer: new Renderer({
        inject: {
          foo: 'bar'
        },
        renderAfterDocumentEvent: 'render-event'
      })
    })
  ])
]
}

staticDirОтносится к адресу страницы предварительно обработанного вывода,routesОтносится к адресу маршрутизации, который необходимо предварительно отобразить.rendererКакой движок рендеринга используется, в настоящее время используетсяV3.4.0Поддержка версийPuppeteerRenderer.injectЭто значение, которое можно получить в процессе предварительного рендеринга.Это значение дает вам возможность решить, следует ли рендерить эту часть кода. Например, следующий код не будет предварительно преобразован вHTMLсередина.

showMessage(){
      if(window.__PRERENDER_INJECTED && window.__PRERENDER_INJECTED.foo =='bar') return;
      this.message = '我是测试预加载拦截';
    }

renderAfterDocumentEventЭто очень важно, это мониторингdocument.dispatchEventсобытие, которое определяет, когда начинать предварительный рендеринг.

new Vue({
  el: '#app',
  router,
  render: h => h(App),
  mounted () {
    // You'll need this for renderAfterDocumentEvent.
    document.dispatchEvent(new Event('render-event'))
  }
});

Пример

Подробности смотрите в официальномVue.js2.0+vue-routerPrerenderSPAExample[3] Примеры.

Принципы и недостатки

prerender-spa-pluginвоспользовалсяPuppeteer[4] Функция обхода страниц.PuppeteerЯвляетсяChromeОфициально произведеноheadlessChromenodeбиблиотека. Он предоставляет ряд API-интерфейсов, которые можно вызывать без пользовательского интерфейса.ChromeОн подходит для различных сценариев, таких как поисковый робот и автоматическая обработка. Это мощно, поэтому легко преобразовать среду выполненияHTMLупакован в файл. ПринципWebpackВ конце этапа сборки запустите локальныйPuppeteer, получить доступ к предварительно обработанному маршруту, а затемPuppeteerВизуализированная страница в выводе наHTMLфайл и создайте каталог, соответствующий маршруту.

Результаты компиляции с официальным примером следующие:

Каждая соответствующая дорога имеет соответствующий статическийHTML. КаждыйHTMLКроме

<div id="app"></div>

этоVueВ дополнение к элементу монтирования есть также статическое содержимое метки.

<!DOCTYPE html><html lang="en"><head>
  <meta charset="utf-8">
  <title>PRODUCTION prerender-spa-plugin</title>
<link rel="shortcut icon" href="/favicon.ico"><style type="text/css"></style><style type="text/css">#app{font-family:Avenir,Helvetica,Arial,sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;text-align:center;color:#2c3e50;margin-top:60px}h1,h2{font-weight:400}ul{list-style-type:none;padding:0}li{display:inline-block;margin:0 10px}a{color:#42b983}</style></head>
<body>
  <div id="app"><div><img src="/logo.png?82b9c7a5a3f405032b1db71a25f67021"> <h1>Welcome to your prerender-spa-plugin Vuejs 2.0 demo app!</h1> <p>汪楠大大about页</p> <p><a href="/" class="router-link-active">Home</a> <a href="/about" class="router-link-exact-active router-link-active">About</a> <a href="/contact" class="">Contact</a></p> <ul></ul> <a href="javascript:;">点击我,看看有什么效果</a> <p>最好不要点我</p></div></div>
<script type="text/javascript" src="/build.js"></script>

</body></html>

Так как для каждого маршрута есть соответствующий маршрутHTML, тогда соответствующийSEOОптимизация не должна быть проблемой. мы можем изменитьtitle,meta. И содержимое страницы уже вHTMLпредставлены непосредственно вjsПодождите, пока медленная загрузка ресурсов вызовет проблему с белым экраном.prerender-spa-pluginДействительно, в определенной степени нашаSEOТребования и проблемы с медленной загрузкой страниц. Но его недостатки все же очевидны.

  • Разные пользователи видят разные страницы, страницы с динамическими данными

  • Часто меняющиеся страницы, отображение данных в реальном времени (например, спортивные игры и т. д.)

  • Слишком много маршрутов, слишком долго строить

правильная осанка

После стольких разговоров каждый должен дать пользователям лучший опыт. По сути, страницы, которые мы делаем, сильно зависят от динамического отображения данных.Если неестественно переключаться между отрендеренной статической страницей и последней отрендеренной страницей, опыт будет очень плохим. мы не можем решитьSEOИли проблема медленной загрузки, приносящая новые проблемы. Так как именно? на самом деле очень просто:LoadingИли Скелетон Экран. Оба они будут переходитьHTMLФрагмент вставлен в<divid="app"></div>середина. однаждыJavaScriptзагружен,VueКогда официальная страница начинает отображаться, переходныйHTMLФрагмент мертв. Взгляните на код ниже

<body>
  <div id="app"><div><div class="j-loading-wrap"><div class="j-mask"></div> <div class="j-loading"><img src="/joy_loading.gif?b494ac2f480615dc87d8797cb1a712da"></div></div> <!----></div></div>
<script type="text/javascript" src="/build.js"></script>

</body>

<skeleton-loading >
    <row 
        :gutter="{
            bottom: '0.1rem'
        }">
        <column :span="'24'">
            <square-skeleton 
                :boxProperties="{
                    height: '0.3rem'
                }"    
            />
        </column>
    </row>
    <row>
        <square-skeleton 
            :boxProperties="{
                height: '3.1rem'
            }"    
        />
    </row>
<skeleton-loading >

LoadingИли каркасный экран предназначен только для улучшения взаимодействия с пользователем, так какое же он имеет отношение к основной части этой статьи? Это связано Обычно при создании эффектов перехода многие из них представляют собой рукописный код, что не способствует обслуживанию и унифицированным стандартам. мы можем использоватьprerender-spa-pluginДля работы он может генерировать статические файлы для всей страницы и выводить наHTML, то для нашегоLoadingкомпонент или первый экран страницыDOMи вывод автоматизации стилей наHTML, разве это не легко? А для скелетного экрана нужно отображать только содержимое первого экрана, поэтому мы можем использовать глобальные переменные плагина, чтобы решить, требуются ли последующие действия по захвату страницы. Это также решает проблему размера каркасного экрана.

Опять таки,SEOДля разрабатываемых в настоящее время приложений очень мало требований, и они в основном являются входными страницами. но сprerender-spa-pluginЕго также можно решить идеально, сгенерировавLoadingНесколько страниц маршрутизации скелетного экрана или несколько страниц маршрутизации скелетного экрана могут быть развернуты серверной частью дляvmВ шаблоне пропишите соответствующийtitleа такжеmeta,использоватьSEOОптимизация.

Приведенное выше состоит в том, чтобы автоматически захватить страницу для генерации экрана скелета, но он все еще находится на этапе исследований. В настоящее время мы все еще используем рукописные компоненты скелетных экранов в производственном проекте. Вы можете обратиться к этомуvue-skeleton-loading[5] компоненты. Используйте предварительно отображаемые плагины в экран скелетLoadingкомпонент или стандартLoadingКомпоненты начинаются сDOMформировать выходные данные для развертывания в рабочей средеHTMLна странице. Общая среда конструирования Webpack — это леса vue-cli Gaea, созданные командой разработчиков JDC. вывести соответствующий html-файл. Компонент представляет собой облегченную библиотеку компонентов Vue, разработанную командой разработчиков интерфейса JDC и широко используемую в мобильных сценариях, таких как JD APP и JD Me: NutUI[6]. Плагин предварительного рендеринга позволяет нам легко вставлять общие компоненты в html, тем самым решая проблемы, упомянутые выше, что является прогрессивным решением.

Суммировать

В этой статье перечислены болевые точки одностраничного интерфейса: медленная загрузка первого экрана и проблема белого экрана.SEO.也给出了渐进的解决方案利用预渲染prerender-spa-pluginВыходVueилиReactОбщие компоненты (компоненты каркасного экрана иLoadingкомпонент) на каждую страницу маршрутизацииHTMLсередина. В будущем мы будем полагаться на плагин предварительного рендеринга для автоматизации схемы вывода экрана скелета Добро пожаловать для обсуждения и общения, пожалуйста, обратите внимание на общедоступную учетную запись исследования полного стека ~

Расширенное чтение

[1] Nuxt.js: https://nuxtjs.org/guide

[2] prerender-spa-plugin: https://github.com/chrisvfritz/prerender-spa-plugin

[3] vue2-webpack-router: https://github.com/chrisvfritz/prerender-spa-plugin/tree/dba55854a95a7a4e9b4aaf4203fb0563739bc58a/examples/vue2-webpack-router

[4] кукольник: https://github.com/GoogleChrome/puppeteer

[5] vue-skeleton-loading: https://github.com/jiingwang/vue-skeleton-loading