vue3.0支援服務端渲染。 Vue支援將元件在服務端直接渲染成HTML字串,作為服務端回應傳回瀏覽器,最後在瀏覽器端將靜態的HTML「啟動」(hydrate) 為能夠互動的用戶端套用。一個由服務端渲染的Vue應用可以被認為是「同構的」 或「通用的,因為應用的大部分程式碼同時運行在服務端和客戶端。vue用服務端渲染的優勢:更快的首屏載入、統一的心智模型、更好的SEO。
本教學操作環境:windows7系統、vue3版,DELL G3電腦。
#vue支援服務端渲染(SSR)。
Vue.js 是一個用於建立客戶端應用程式的框架。預設情況下,Vue 元件的職責是在瀏覽器中產生和操作DOM。然而,Vue 也支援將元件在服務端直接渲染成HTML 字串,作為服務端回應傳回瀏覽器,最後在瀏覽器端將靜態的HTML「啟動」(hydrate) 為能夠互動的客戶端應用。
一個由服務端渲染的Vue.js 應用程式也可以被認為是「同構的」(Isomorphic) 或「通用的」(Universal),因為應用程式的大部分程式碼同時運行在服務端和客戶端。
為什麼要用服務端渲染(SSR)?
與客戶端的單頁應用(SPA) 相比,SSR 的優勢主要在於:
更快的首屏載入:這一點在慢網速或運行緩慢的設備上尤為重要。服務端渲染的HTML 無需等到所有的JavaScript 都下載並執行完成之後才顯示,所以你的用戶將會更快地看到完整渲染的頁面。除此之外,數據獲取過程在首次訪問時在服務端完成,相較於從客戶端獲取,可能有更快的資料庫連線。這通常可以帶來更高的核心Web 指標評分、更好的使用者體驗,而對於那些「首屏載入速度與轉換率直接相關」的應用來說,這點可能至關重要。【相關推薦:vuejs影片教學、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.</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支援服務端渲染嗎的詳細內容。更多資訊請關注PHP中文網其他相關文章!