Vue 服務(wù)端渲染(SSR)

什么是服務(wù)器端渲染 (SSR)?


Vue.js 是構(gòu)建客戶端應(yīng)用程序的框架。默認(rèn)情況下,可以在瀏覽器中輸出 Vue 組件,進(jìn)行生成 DOM 和操作 DOM。然而,也可以將同一個(gè)組件渲染為服務(wù)器端的 HTML 字符串,將它們直接發(fā)送到瀏覽器,最后將這些靜態(tài)標(biāo)記"激活"為客戶端上完全可交互的應(yīng)用程序。

服務(wù)器渲染的 Vue.js 應(yīng)用程序也可以被認(rèn)為是"同構(gòu)"或"通用",因?yàn)閼?yīng)用程序的大部分代碼都可以在服務(wù)器客戶端上運(yùn)行。

為什么使用服務(wù)器端渲染 (SSR)?


與傳統(tǒng) SPA (單頁(yè)應(yīng)用程序 (Single-Page Application)) 相比,服務(wù)器端渲染 (SSR) 的優(yōu)勢(shì)主要在于:

  • 更好的 SEO,由于搜索引擎爬蟲(chóng)抓取工具可以直接查看完全渲染的頁(yè)面。
  • 更快的內(nèi)容到達(dá)時(shí)間 (time-to-content),特別是對(duì)于緩慢的網(wǎng)絡(luò)情況或運(yùn)行緩慢的設(shè)備。無(wú)需等待所有的 JavaScript 都完成下載并執(zhí)行,才顯示服務(wù)器渲染的標(biāo)記,所以你的用戶將會(huì)更快速地看到完整渲染的頁(yè)面。通常可以產(chǎn)生更好的用戶體驗(yàn),并且對(duì)于那些「內(nèi)容到達(dá)時(shí)間(time-to-content) 與轉(zhuǎn)化率直接相關(guān)」的應(yīng)用程序而言,服務(wù)器端渲染 (SSR) 至關(guān)重要。

使用服務(wù)器端渲染 (SSR) 時(shí)還需要有一些權(quán)衡之處:

  • 開(kāi)發(fā)條件所限。瀏覽器特定的代碼,只能在某些生命周期鉤子函數(shù) (lifecycle hook) 中使用;一些外部擴(kuò)展庫(kù) (external library) 可能需要特殊處理,才能在服務(wù)器渲染應(yīng)用程序中運(yùn)行。
  • 涉及構(gòu)建設(shè)置和部署的更多要求。與可以部署在任何靜態(tài)文件服務(wù)器上的完全靜態(tài)單頁(yè)面應(yīng)用程序 (SPA) 不同,服務(wù)器渲染應(yīng)用程序,需要處于 Node.js server 運(yùn)行環(huán)境。
  • 更多的服務(wù)器端負(fù)載。在 Node.js 中渲染完整的應(yīng)用程序,顯然會(huì)比僅僅提供靜態(tài)文件的 server 更加大量占用 CPU 資源 (CPU-intensive - CPU 密集),因此如果你預(yù)料在高流量環(huán)境 (high traffic) 下使用,請(qǐng)準(zhǔn)備相應(yīng)的服務(wù)器負(fù)載,并明智地采用緩存策略。

服務(wù)器端渲染 vs 預(yù)渲染 (SSR vs Prerendering)


如果你調(diào)研服務(wù)器端渲染 (SSR) 只是用來(lái)改善少數(shù)營(yíng)銷頁(yè)面(例如 /, /about, /contact 等)的 SEO,那么你可能需要預(yù)渲染。無(wú)需使用 web 服務(wù)器實(shí)時(shí)動(dòng)態(tài)編譯 HTML,而是使用預(yù)渲染方式,在構(gòu)建時(shí) (build time) 簡(jiǎn)單地生成針對(duì)特定路由的靜態(tài) HTML 文件。優(yōu)點(diǎn)是設(shè)置預(yù)渲染更簡(jiǎn)單,并可以將你的前端作為一個(gè)完全靜態(tài)的站點(diǎn)。

項(xiàng)目(一)


在項(xiàng)目一中我們創(chuàng)建一個(gè)最原始的SSR項(xiàng)目,便于理解SSR的原理

首先創(chuàng)建一個(gè)文件夾ssr,然后進(jìn)入ssr

$ cd ssr
$ npm init

創(chuàng)建server文件夾,創(chuàng)建一個(gè)app.js文件,下載相應(yīng)的插件

$ npm i vue
$ npm i vue-server-renderer
$ npm i express
# vue  vue-server-renderer 版本要一致

app.js文件內(nèi)容為:

/**** app.js ***/

//創(chuàng)建一個(gè) Vue 實(shí)例
const Vue = require('vue');
const express = require('express')();
const app = new Vue({
  template: `<div>Hello World</div>`
});

//創(chuàng)建一個(gè)renderer
const renderer = require('vue-server-renderer').createRenderer();

//相應(yīng)路由請(qǐng)求
express.get('/', (req, res) => {
  //將Vue實(shí)例渲染為HTML
  renderer.renderToString(app, (err, html) => {
    if (err) throw err;
    console.log("==html==", html);
    res.send(
      `
       <!DOCTYPE html>
       <html lang="en">
          <head>
             <meta charset="UTF-8"></meta>
             <title>SSR渲染頁(yè)面1</title>
          </head>
          <body>
             ${html}
          </body>
       </html>
      `
    );
  });

   //在 2.5.0 + ,如果沒(méi)有傳入回調(diào)函數(shù),則會(huì)返回 Promise
   // renderer.renderToString(app).then(html => {
   //   console.log(html);
   //   res.send(
   //     `
   //     <!DOCTYPE html>
   //     <html lang="en">
   //        <head>
   //           <meta charset="UTF-8"></meta>
   //           <title>SSR渲染頁(yè)面1</title>
   //        </head>
   //        <body>
   //           ${html}
   //        </body>
   //     </html>
   //    `
   //   );
   // }).catch(err => {
   //  console.log(err);
  //});
});

//服務(wù)器監(jiān)聽(tīng)地址
express.listen(8082, () => {
  console.log('服務(wù)器已啟動(dòng)');
});

ssr文件夾目錄結(jié)構(gòu):

/* ssr目錄結(jié)構(gòu) */
| - node_modules
  - package.json
  - package-lock.json
  - server
     |  -app.js

啟動(dòng)服務(wù):

$ node app

打開(kāi)瀏覽器,地址欄輸入:

http://localhost:8082

我們可以看到,頁(yè)面加載成功:


image.png

打開(kāi)chrome開(kāi)發(fā)者工具查看Network可以看到:

image.png

我們可以看到Vue實(shí)例中的模板已經(jīng)被渲染到了html頁(yè)面并返回到了客戶端
服務(wù)端渲染的核心就在于:通過(guò) vue-server-renderer 插件的renderToString()方法,將Vue實(shí)例轉(zhuǎn)換為字符串插入到html文件中

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容