最近在把一個(gè)c端的項(xiàng)目重構(gòu)成首屏服務(wù)端渲染(SSR:server side render)
項(xiàng)目用到的技術(shù): React 、webpack、koa2、webpack
對(duì)于重構(gòu)成SSR,redux并不是必須的,所以沒(méi)用redux
本篇文章先講述一些理論的東西,之后會(huì)寫代碼篇
一、 什么是服務(wù)端渲染
簡(jiǎn)單理解是將組件或頁(yè)面通過(guò)服務(wù)器生成html字符串,再發(fā)送到瀏覽器,最后將靜態(tài)標(biāo)記"混合"為客戶端上完全交互的應(yīng)用程序
如下圖所示,
左圖頁(yè)面沒(méi)使用服務(wù)渲染,當(dāng)請(qǐng)求user頁(yè)面時(shí),返回的body里為空,之后執(zhí)行js將html結(jié)構(gòu)注入到body里,結(jié)合css顯示出來(lái);
右圖頁(yè)面使用了服務(wù)端渲染,當(dāng)請(qǐng)求user頁(yè)面時(shí),返回的body里已經(jīng)有了首屏的html結(jié)構(gòu),之后結(jié)合css顯示出來(lái)


二、 使用SSR的利弊
SSR的優(yōu)勢(shì)
1. 更利于SEO。
不同爬蟲工作原理類似,只會(huì)爬取源碼,不會(huì)執(zhí)行網(wǎng)站的任何腳本(Google除外,據(jù)說(shuō)Googlebot可以運(yùn)行javaScript)。使用了React或者其它MVVM框架之后,頁(yè)面大多數(shù)DOM元素都是在客戶端根據(jù)js動(dòng)態(tài)生成,可供爬蟲抓取分析的內(nèi)容大大減少(如圖一)。另外,瀏覽器爬蟲不會(huì)等待我們的數(shù)據(jù)完成之后再去抓取我們的頁(yè)面數(shù)據(jù)。服務(wù)端渲染返回給客戶端的是已經(jīng)獲取了異步數(shù)據(jù)并執(zhí)行JavaScript腳本的最終HTML,網(wǎng)絡(luò)爬中就可以抓取到完整頁(yè)面的信息。
2. 更利于首屏渲染
首屏的渲染是node發(fā)送過(guò)來(lái)的html字符串,并不依賴于js文件了,這就會(huì)使用戶更快的看到頁(yè)面的內(nèi)容。尤其是針對(duì)大型單頁(yè)應(yīng)用,打包后文件體積比較大,普通客戶端渲染加載所有所需文件時(shí)間較長(zhǎng),首頁(yè)就會(huì)有一個(gè)很長(zhǎng)的白屏等待時(shí)間。
SSR的局限
- 服務(wù)端壓力較大
本來(lái)是通過(guò)客戶端完成渲染,現(xiàn)在統(tǒng)一到服務(wù)端node服務(wù)去做。尤其是高并發(fā)訪問(wèn)的情況,會(huì)大量占用服務(wù)端CPU資源;
- 開發(fā)條件受限
在服務(wù)端渲染中,只會(huì)執(zhí)行到componentDidMount之前的生命周期鉤子,因此項(xiàng)目引用的第三方的庫(kù)也不可用其它生命周期鉤子,這對(duì)引用庫(kù)的選擇產(chǎn)生了很大的限制;
- 學(xué)習(xí)成本相對(duì)較高
除了對(duì)webpack、React要熟悉,還需要掌握node、Koa2等相關(guān)技術(shù)。相對(duì)于客戶端渲染,項(xiàng)目構(gòu)建、部署過(guò)程更加復(fù)雜。
三、 時(shí)間耗時(shí)比較
-
數(shù)據(jù)請(qǐng)求
由服務(wù)端請(qǐng)求首屏數(shù)據(jù),而不是客戶端請(qǐng)求首屏數(shù)據(jù),這是“快”的一個(gè)主要原因。服務(wù)端在內(nèi)網(wǎng)進(jìn)行請(qǐng)求,數(shù)據(jù)響應(yīng)速度快??蛻舳嗽诓煌W(wǎng)絡(luò)環(huán)境進(jìn)行數(shù)據(jù)請(qǐng)求,且外網(wǎng)http請(qǐng)求開銷大,導(dǎo)致時(shí)間差。 下圖為服務(wù)端渲染的數(shù)據(jù)請(qǐng)求路線和客戶端渲染的數(shù)據(jù)請(qǐng)求路線圖


- html渲染
服務(wù)端渲染是先向后端服務(wù)器請(qǐng)求數(shù)據(jù),然后生成完整首屏html返回給瀏覽器;而客戶端渲染是等js代碼下載、加載、解析完成后再請(qǐng)求數(shù)據(jù)渲染,等待的過(guò)程頁(yè)面是什么都沒(méi)有的,就是用戶看到的白屏。就是服務(wù)端渲染不需要等待js代碼下載完成并請(qǐng)求數(shù)據(jù),就可以返回一個(gè)已有完整數(shù)據(jù)的首屏頁(yè)面。
具體流程可參考下面兩張圖

