SPA單頁(yè)面應(yīng)用
-
優(yōu)點(diǎn)
- 用戶(hù)體驗(yàn)好
- 開(kāi)發(fā)效率高
- 渲染性能好
- 可維護(hù)性好
缺點(diǎn)
首屏渲染時(shí)間長(zhǎng)
不利于SEO
通過(guò)服務(wù)端渲染首屏直出,解決 SPA 應(yīng)用首屏渲染慢以及不利于SEO問(wèn)題
通過(guò)客戶(hù)端渲染接管頁(yè)面內(nèi)容交互得到更好的用戶(hù)體驗(yàn)
這種方式通常稱(chēng)為現(xiàn)代化的服務(wù)端渲染,也叫同構(gòu)渲染
這種方式構(gòu)建的應(yīng)用稱(chēng)之為服務(wù)端渲染應(yīng)用或者式同構(gòu)應(yīng)用
傳統(tǒng)服務(wù)端渲染

圖片.png
//nodejs創(chuàng)建一個(gè)服務(wù) 將頁(yè)面模板與數(shù)據(jù)的渲染結(jié)果 發(fā)送給客戶(hù)端 渲染頁(yè)面
const express = require('express') //模板引擎 npm i express
const fs = require('fs')
const template = require('art-template') //模板引擎 npm i art-template
const app = express()
app.get('/', (req, res) => {
// 1. 獲取頁(yè)面模板
const templateStr = fs.readFileSync('./index.html', 'utf-8') //獲取頁(yè)面模板文件
// 2. 獲取數(shù)據(jù)
const data = JSON.parse(fs.readFileSync('./data.json', 'utf-8')) //讀取數(shù)據(jù)文件
// 3. 渲染:數(shù)據(jù) + 模板 = 最終結(jié)果
const html = template.render(templateStr, data)
// 4. 把渲染結(jié)果發(fā)送給客戶(hù)端
res.send(html)
})
app.get('/about', (req, res) => {
res.end(fs.readFileSync('./about.html'))
})
app.listen(3000, () => console.log(''server"))
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>傳統(tǒng)的服務(wù)端渲染</title>
</head>
<body>
<h1>傳統(tǒng)的服務(wù)端渲染</h1>
<h2>{{ data }}</h2>
</body>
</html>
缺點(diǎn)
- 前后端代碼完全耦合在一起,不利于開(kāi)發(fā)和維護(hù)
- 前端沒(méi)有足夠發(fā)揮空間
- 服務(wù)端壓力大
- 用戶(hù)體驗(yàn)一般
客戶(hù)端渲染

圖片.png
缺點(diǎn)
- 首屏渲染慢
頁(yè)面請(qǐng)求 -> js請(qǐng)求 -> 動(dòng)態(tài)數(shù)據(jù)請(qǐng)求(所以耗時(shí)較長(zhǎng)) - 不利于SEO
同構(gòu)渲染
后端渲染與前端渲染的結(jié)合
- 基于 React,Vue 等框架,客戶(hù)端渲染和服務(wù)器端渲染的結(jié)合
- 在服務(wù)器端執(zhí)行一次,用于實(shí)現(xiàn)服務(wù)器端渲染(首屏直出)
- 在客戶(hù)端再執(zhí)行一次,用于接管頁(yè)面交互
- 核心解決SEO和首屏渲染慢的問(wèn)題
-
擁有傳統(tǒng)服務(wù)端渲染的優(yōu)點(diǎn),也有客戶(hù)端渲染的優(yōu)點(diǎn)
圖片.png
同構(gòu)渲染應(yīng)用的問(wèn)題
- 開(kāi)發(fā)條件所限
- 瀏覽器特定的代碼只能在某些生命周期鉤子函數(shù)中使用
- 一些外部擴(kuò)展庫(kù)可能需要特殊處理才能在服務(wù)端渲染應(yīng)用中運(yùn)行
- 不能在服務(wù)端渲染期間操作DOM
- 某些代碼操作需要區(qū)分運(yùn)行環(huán)境
-
涉及構(gòu)建設(shè)置和部署的更多要求
圖片.png - 更多的服務(wù)器端負(fù)載
- 在Node中渲染完整的應(yīng)用程序,相比僅僅提供靜態(tài)文件的服務(wù)器 需要大量占用CPU資源
- 如果應(yīng)用在高流量環(huán)境下使用,需要準(zhǔn)備響應(yīng)的服務(wù)器負(fù)載
- 需要更多的服務(wù)端渲染優(yōu)化工作處理
Nuxt.js
- 一個(gè)基于 Vue.js 生態(tài)的第三方開(kāi)源服務(wù)端渲染應(yīng)用框架
- 可以輕松的使用Vue.js 技術(shù)棧構(gòu)建同構(gòu)應(yīng)用
Nuxt.js使用方式 - 初始項(xiàng)目
- 已有的Node.js服務(wù)端項(xiàng)目
- 直接把Nuxt當(dāng)作一個(gè)中間件集成到Node Web Server中
- 現(xiàn)有的Vue.js項(xiàng)目
- 非常熟悉Nuxt.js
- 至少百分之10的代碼改動(dòng)
Nuxt.js 異步數(shù)據(jù)-asyncData 方法
- 基本用法
- 它會(huì)將 asyncData 返回的數(shù)據(jù)融合組件 data 方法返回?cái)?shù)據(jù)一并給組件
- 調(diào)用時(shí)機(jī):服務(wù)端渲染期間和客戶(hù)端路由更新之前
- 注意事項(xiàng)
- 只能在頁(yè)面組件中使用
- 沒(méi)有this,因?yàn)樗墙M件初始化之前被調(diào)用的
當(dāng)想要?jiǎng)討B(tài)頁(yè)面內(nèi)容有利于SEO或者是提升首屏渲染速度的時(shí)候,就在 asyncData中發(fā)請(qǐng)求 拿數(shù)據(jù)

