Vue 使用預渲染代替 SSR

zmxyzmxy1234發表於2020-07-01

前段時間瞭解到頁面有幾種渲染方式:SPA SSR,以前寫的一個網站但是用的渲染方式是SPA,導致搜尋引擎爬蟲抓不到任何資訊,對SEO最佳化不很好,本想改成SSR,但是改動配置很多,弄來弄去怕影響開發,今天在Vue官網看到預渲染,今天試了下,感覺是一個折中的方法,而且配置改動不大,大家可以試試

什麼是伺服器端渲染 (SSR)?

Vue.js 是構建客戶端應用程式的框架。預設情況下,可以在瀏覽器中輸出 Vue 元件,進行生成 DOM 和操作 DOM。然而,也可以將同一個元件渲染為伺服器端的 HTML 字串,將它們直接傳送到瀏覽器,最後將這些靜態標記”啟用”為客戶端上完全可互動的應用程式。

伺服器渲染的 Vue.js 應用程式也可以被認為是”同構”或”通用”,因為應用程式的大部分程式碼都可以在伺服器客戶端上執行。

為什麼使用伺服器端渲染 (SSR)?

與傳統 SPA (單頁應用程式 (Single-Page Application)) 相比,伺服器端渲染 (SSR) 的優勢主要在於:

  • 更好的 SEO,由於搜尋引擎爬蟲抓取工具可以直接檢視完全渲染的頁面。

    請注意,截至目前,Google 和 Bing 可以很好對同步 JavaScript 應用程式進行索引。在這裡,同步是關鍵。如果你的應用程式初始展示 loading 菊花圖,然後透過 Ajax 獲取內容,抓取工具並不會等待非同步完成後再行抓取頁面內容。也就是說,如果 SEO 對你的站點至關重要,而你的頁面又是非同步獲取內容,則你可能需要伺服器端渲染(SSR)解決此問題。

  • 更快的內容到達時間 (time-to-content),特別是對於緩慢的網路情況或執行緩慢的裝置。無需等待所有的 JavaScript 都完成下載並執行,才顯示伺服器渲染的標記,所以你的使用者將會更快速地看到完整渲染的頁面。通常可以產生更好的使用者體驗,並且對於那些「內容到達時間(time-to-content) 與轉化率直接相關」的應用程式而言,伺服器端渲染 (SSR) 至關重要。

使用伺服器端渲染 (SSR) 時還需要有一些權衡之處:

  • 開發條件所限。瀏覽器特定的程式碼,只能在某些生命週期鉤子函式 (lifecycle hook) 中使用;一些外部擴充套件庫 (external library) 可能需要特殊處理,才能在伺服器渲染應用程式中執行。

  • 涉及構建設定和部署的更多要求。與可以部署在任何靜態檔案伺服器上的完全靜態單頁面應用程式 (SPA) 不同,伺服器渲染應用程式,需要處於 Node.js server 執行環境。

  • 更多的伺服器端負載。在 Node.js 中渲染完整的應用程式,顯然會比僅僅提供靜態檔案的 server 更加大量佔用 CPU 資源 (CPU-intensive - CPU 密集),因此如果你預料在高流量環境 (high traffic) 下使用,請準備相應的伺服器負載,並明智地採用快取策略。

在對你的應用程式使用伺服器端渲染 (SSR) 之前,你應該問的第一個問題是,是否真的需要它。這主要取決於內容到達時間 (time-to-content) 對應用程式的重要程度。例如,如果你正在構建一個內部儀表盤,初始載入時的額外幾百毫秒並不重要,這種情況下去使用伺服器端渲染 (SSR) 將是一個小題大作之舉。然而,內容到達時間 (time-to-content) 要求是絕對關鍵的指標,在這種情況下,伺服器端渲染 (SSR) 可以幫助你實現最佳的初始載入效能。

伺服器端渲染 vs 預渲染 (SSR vs Prerendering)

如果你調研伺服器端渲染 (SSR) 只是用來改善少數營銷頁面(例如 /, /about, /contact 等)的 SEO,那麼你可能需要預渲染。無需使用 web 伺服器實時動態編譯 HTML,而是使用預渲染方式,在構建時 (build time) 簡單地生成針對特定路由的靜態 HTML 檔案。優點是設定預渲染更簡單,並可以將你的前端作為一個完全靜態的站點。

如果你使用 webpack,你可以使用 prerender-spa-plugin 輕鬆地新增預渲染。它已經被 Vue 應用程式廣泛測試 - 事實上,作者是 Vue 核心團隊的成員。

使用方法

  • vue-router必須是history模式
    const router = new VueRouter({
    mode: 'history',
    routes: [...]
    })
  • 安裝預渲染核心:prerender-spa-plugin
    yarn add prerender-spa-plugin -D
  • 在vue.config.js配置(低版本vue寫在build/webpack.prod.conf.js)
    const PrerenderSPAPlugin = require('prerender-spa-plugin')
    const Renderer = PrerenderSPAPlugin.PuppeteerRenderer
    module.exports={
      // 因為高版本Vue將配置檔案整合到了vue.config.js,所以原先寫在webpack配置裡的都需要寫在configureWebpack裡
      configureWebpack: {
          // plugins外掛裡書寫
          plugins: [
             new PrerenderSPAPlugin({
                // 生成檔案的路徑,這個目錄只能有一級。若目錄層次大於一級,在生成的時候不會有任何錯誤提示,在預渲染的時候只會卡著不動
                staticDir: path.join(__dirname, './dist'),
                // 對應自己的路由檔案
                routes: [ '/', '/article'],
                // 若沒有這段則不會進行預編譯
                renderer: new Renderer({
                  inject: {
                    foo: 'bar'
                  },
                  headless: false,
                  // 在 main.js 中 document.dispatchEvent(new Event('render-event')),兩者的事件名稱要對應上。
                  renderAfterDocumentEvent: 'render-event'
                })
              }),
          ]
      }
    }
  • 在mian.js配置,在mounted函式里增加 document.dispatchEvent(new Event(‘render-event’))
    new Vue({
    el: '#app',
    router,
    store,
    render:h=>h(App),
    mounted(){
        document.dispatchEvent(new Event('render-event'))
    }
    })
  • yarn run build打包專案,看到自己的頁面被提前生成就OK了

安裝vue-meta-info外掛,網頁meta標籤

  • yarn安裝
    yarn add vue-meta-info
  • 在mian.js配置
    import MetaInfo from 'vue-meta-info' 
    Vue.use(MetaInfo)
  • 在XXOO.vue檔案中配置
    export default {
      // 這些程式碼會轉成網頁的meta標籤裡的內容
      metaInfo: {
          title: '標題',
          meta: [
              {
                  name: 'keywords',
                  content: '關鍵字'
              },
              {
                  name: 'description',
                  content: '網頁描述'
              }
          ]
      }
本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章