vue3.0支援伺服器端渲染嗎

2022-12-15 18:01:33

vue3.0支援伺服器端渲染。Vue支援將元件在伺服器端直接渲染成HTML字串,作為伺服器端響應返回給瀏覽器,最後在瀏覽器端將靜態的HTML「啟用」(hydrate) 為能夠互動的使用者端應用。一個由伺服器端渲染的Vue應用可以被認為是「同構的」 或「通用的,因為應用的大部分程式碼同時執行在伺服器端和使用者端。vue用伺服器端渲染的優勢:更快的首屏載入、統一的心智模型、更好的SEO。

前端(vue)入門到精通課程,老師線上輔導:聯絡老師
Apipost = Postman + Swagger + Mock + Jmeter 超好用的API偵錯工具:

本教學操作環境:windows7系統、vue3版,DELL G3電腦。

vue支援伺服器端渲染(SSR)。

Vue.js 是一個用於構建使用者端應用的框架。預設情況下,Vue 元件的職責是在瀏覽器中生成和操作 DOM。然而,Vue 也支援將元件在伺服器端直接渲染成 HTML 字串,作為伺服器端響應返回給瀏覽器,最後在瀏覽器端將靜態的 HTML「啟用」(hydrate) 為能夠互動的使用者端應用。

一個由伺服器端渲染的 Vue.js 應用也可以被認為是「同構的」(Isomorphic) 或「通用的」(Universal),因為應用的大部分程式碼同時執行在伺服器端和使用者端。

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

與使用者端的單頁應用 (SPA) 相比,SSR 的優勢主要在於:

  • 更快的首屏載入:這一點在慢網速或者執行緩慢的裝置上尤為重要。伺服器端渲染的 HTML 無需等到所有的 JavaScript 都下載並執行完成之後才顯示,所以你的使用者將會更快地看到完整渲染的頁面。除此之外,資料獲取過程在首次存取時在伺服器端完成,相比於從使用者端獲取,可能有更快的資料庫連線。這通常可以帶來更高的核心 Web 指標評分、更好的使用者體驗,而對於那些「首屏載入速度與轉化率直接相關」的應用來說,這點可能至關重要。【相關推薦:、】

  • 統一的心智模型:你可以使用相同的語言以及相同的宣告式、面向元件的心智模型來開發整個應用,而不需要在後端模板系統和前端框架之間來回切換。

  • 更好的 SEO:搜尋引擎爬蟲可以直接看到完全渲染的頁面。

使用 SSR 時還有一些權衡之處需要考量:

  • 開發中的限制。瀏覽器端特定的程式碼只能在某些生命週期勾點中使用;一些外部庫可能需要特殊處理才能在伺服器端渲染的應用中執行。

  • 更多的與構建設定和部署相關的要求。伺服器端渲染的應用需要一個能讓 Node.js 伺服器執行的環境,不像完全靜態的 SPA 那樣可以部署在任意的靜態檔案伺服器上。

  • 更高的伺服器端負載。在 Node.js 中渲染一個完整的應用要比僅僅託管靜態檔案更加佔用 CPU 資源,因此如果你預期有高流量,請為相應的伺服器負載做好準備,並採用合理的快取策略。

伺服器端渲染 (SSR) vs. 靜態站點生成(SSG)

靜態站點生成 (Static-Site Generation,縮寫為 SSG),也被稱為預渲染,是另一種流行的構建快速網站的技術。如果用伺服器端渲染一個頁面所需的資料對每個使用者來說都是相同的,那麼我們可以只渲染一次,提前在構建過程中完成,而不是每次請求進來都重新渲染頁面。預渲染的頁面生成後作為靜態 HTML 檔案被伺服器託管。

SSG 保留了和 SSR 應用相同的效能表現:它帶來了優秀的首屏載入效能。同時,它比 SSR 應用的花銷更小,也更容易部署,因為它輸出的是靜態 HTML 和資原始檔。這裡的關鍵詞是靜態:SSG 僅可以用於消費靜態資料的頁面,即資料在構建期間就是已知的,並且在多次部署期間不會改變。每當資料變化時,都需要重新部署。

如果你調研 SSR 只是為了優化為數不多的行銷頁面的 SEO (例如 /、/about 和 /contact 等),那麼你可能需要 SSG 而不是 SSR。SSG 也非常適合構建基於內容的網站,比如檔案站點或者部落格。事實上,你現在正在閱讀的這個網站就是使用 VitePress 靜態生成的,它是一個由 Vue 驅動的靜態站點生成器。

Hello World

準備在行動中體驗伺服器端渲染吧。伺服器端渲染(即SSR)聽起來很複雜,不過一個簡單的Node指令碼只需要3步就可以實現這個功能:

// 步驟 1:建立一個Vue範例
var Vue = require('vue')
var app = new Vue({
  render: function (h) {
    return h('p', 'hello world')
  }
})

// 步驟 2: 建立一個渲染器
var renderer = require('vue-server-renderer').createRenderer()

// 步驟 3: 將 Vue範例 渲染成 HTML

renderer.renderToString(app, function (error, html) {
  if (error) throw error
  console.log(html)
  // => <p server-rendered="true">hello world</p>
})
登入後複製

這並不困難。當然這個範例比大部分應用都簡單,來探討這些功能怎樣運作

通過Express Web伺服器實現簡單的伺服器端渲染

如果沒有一個Web伺服器,很難說是伺服器端渲染,所以我們來補充它。我們將構建一個非常簡單的伺服器端渲染應用,只用ES5,也不帶其他構建步驟或Vue外掛。

啟動一個應用告訴使用者他們在一個頁面上花了多少時間。

new Vue({
  template: '<div>你已經在這花了 {{ counter }} 秒。</div>',
  data: {
    counter: 0
  },
  created: function () {
    var vm = this
    setInterval(function () {
      vm.counter += 1
    }, 1000)
  }
})
登入後複製

為了適應伺服器端渲染,我們需要進行一些修改,讓它可以在瀏覽器和Node中渲染:

  • 在瀏覽器中,將我們的應用範例新增到全域性上下文( window)上,我們可以安裝它。

  • 在Node中,匯出一個工廠函數讓我們可以為每個請求建立應用範例。

實現這個需要一點模板:

// assets/app.js
(function () { 'use strict'
  var createApp = function () {
    // ---------------------
    // 開始常用的應用程式碼
    // ---------------------

    // 主要的Vue範例必須返回,並且有一個根節點在id "app"上,這樣使用者端可以載入它。

    return new Vue({
      template: '<div id="app">你已經在這花了 {{ counter }} 秒。</div>',
      data: {
        counter: 0
      },
      created: function () {
        var vm = this
        setInterval(function () {
          vm.counter += 1
        }, 1000)
      }
    })

    // -------------------
    // 結束常用的應用程式碼
    // -------------------
  }
  if (typeof module !== 'undefined' && module.exports) {
    module.exports = createApp
  } else {
    this.app = createApp()
  }
}).call(this)
登入後複製

現在有了應用程式碼,接著加一個 html檔案。

<!-- index.html -->
<!DOCTYPE html>
<html>
<head>
  <title>My Vue App</title>
  <script src="/assets/vue.js"></script>
</head>
<body>
  <div id="app"></div>
  <script src="/assets/app.js"></script>
  <script>app.$mount('#app')</script>
</body>
</html>
登入後複製

主要參照assets資料夾中我們先前建立的app.js,以及vue.js檔案,我們就有了一個可以執行的單頁面應用

然後為了實現伺服器端渲染,在伺服器端需要加一個步驟。

// server.js
'use strict'

var fs = require('fs')
var path = require('path')

// 定義全域性的Vue為了伺服器端的app.js
global.Vue = require('vue')

// 獲取HTML佈局
var layout = fs.readFileSync('./index.html', 'utf8')

// 建立一個渲染器
var renderer = require('vue-server-renderer').createRenderer()

// 建立一個Express伺服器
var express = require('express')
var server = express()

// 部署靜態資料夾為 "assets"資料夾
server.use('/assets', express.static(
  path.resolve(__dirname, 'assets')
))

// 處理所有的Get請求
server.get('*', function (request, response) {
  // 渲染我們的Vue應用為一個字串
  renderer.renderToString(
    // 建立一個應用範例
    require('./assets/app')(),
    // 處理渲染結果
    function (error, html) {
      // 如果渲染時發生了錯誤
      if (error) {
        // 列印錯誤到控制檯
        console.error(error)
        // 告訴使用者端錯誤
        return response
          .status(500)
          .send('Server Error')
      }
      // 傳送佈局和HTML檔案
      response.send(layout.replace('<div id="app"></div>', html))
    }
  )
})

// 監聽5000埠
server.listen(5000, function (error) {
  if (error) throw error
  console.log('Server is running at localhost:5000')
})
登入後複製

這樣就完成了。整個範例,克隆下來深度實驗。一旦它在本地執行時,你可以通過在頁面右擊選擇頁面資源(或類似操作)確認服務選渲染真的執行了。可以在body中看到:

<div id="app" server-rendered="true">You have been here for 0 seconds&period;</div>
登入後複製

代替:

<div id="app"></div>
登入後複製

流式響應

Vue還支援流式渲染,優先選擇適用於支援流的Web伺服器。允許HTML一邊生成一般寫入相應流,而不是在最後一次全部寫入。其結果是請求服務速度更快,沒有缺點!

為了使上一節應用程式碼適用流式渲染,可以簡單的替換 server.get('*',...)為下面的程式碼:

// 拆分佈局成兩段HTML
var layoutSections = layout.split('<div id="app"></div>')
var preAppHTML = layoutSections[0]
var postAppHTML = layoutSections[1]

// 處理所有的Get請求
server.get('*', function (request, response) {
  // 渲染我們的Vue範例作為流
  var stream = renderer.renderToStream(require('./assets/app')())

  // 將預先的HTML寫入響應
  response.write(preAppHTML)

  // 每當新的塊被渲染
  stream.on('data', function (chunk) {
    // 將塊寫入響應
    response.write(chunk)
  })

  // 當所有的塊被渲染完成
  stream.on('end', function () {
    // 將post-app HTML寫入響應
    response.end(postAppHTML)
  })

  // 當渲染時發生錯誤
  stream.on('error', function (error) {
    // 列印錯誤到控制檯
    console.error(error)
    // 告訴客服端發生了錯誤
    return response
      .status(500)
      .send('Server Error')
  })
})
登入後複製

這不比之前的版本複雜,甚至這對你來說都不是個新概念。我們做了:

  • 建立流

  • 在應用響應前寫入HTML

  • 在可獲得時將應用HTML寫入響應

  • 在響應最後寫入HTML

  • 處理任何錯誤

元件快取

Vue的伺服器端渲染預設非常快,但是你可以通過快取渲染好的元件進一步提高效能。這被認為是一種先進的功能,但是,如果快取了錯誤的元件(或者正確的元件帶有錯誤的內容)將導致應用渲染出錯。特別注意:

不應該快取元件包含子元件依賴全域性狀態(例如來自vuex的狀態)。如果這麼做,子元件(事實上是整個子樹)也會被快取。所以要特別注意帶有slots片段或者子元件的情況。

設定

在警告情況之外的,我們可以用下面的方法快取元件。

首先,你需要提供給渲染器一個 快取物件。這有個簡單的範例使用 lru-cache

var createRenderer = require('vue-server-renderer').createRenderer
var lru = require('lru-cache')

var renderer = createRenderer({
  cache: lru(1000)
})
登入後複製

這將快取高達1000個獨立的渲染。對於更進一步快取到內容中的設定,看lru-cache設定

然後對於你想快取的元件,你可以為他們提供:

  • 一個唯一的名字

  • 一個 serverCacheKey函數,返回一個唯一的元件作用域

例如:

Vue.component({
  name: 'list-item',
  template: '<li>{{ item.name }}</li>',
  props: ['item'],
  serverCacheKey: function (props) {
    return props.item.type + '::' + props.item.id
  }
})
登入後複製

快取的理想元件

任何純元件可以被安全快取 - 這是保證給任何元件傳遞一樣的資料產生相同的HTML。這些場景的例子包括:

  • 靜態的元件 (例如 總是嘗試一樣的HTML,所以 serverCacheKey 函數可以被返回 true)

  • 列表元件(當有大量列表,快取他們可以改善效能)

  • 通用UI元件 (例如 buttons, alerts, 等等 - 至少他們通過props獲取資料而不是 slots或者子元件)

說明:

現在,應該理解伺服器端渲染背後的基本概念了。但是,構建過程、路由、Vuex每一個都有自己的注意事項。

(學習視訊分享:、)

以上就是vue3.0支援伺服器端渲染嗎的詳細內容,更多請關注TW511.COM其它相關文章!