摘要:本文只是對(duì)官方文檔和對(duì)官方的個(gè)人學(xué)習(xí)總結(jié),說(shuō)得不夠完整的請(qǐng)見(jiàn)諒本文主要對(duì)以下幾方面內(nèi)容對(duì)的內(nèi)容進(jìn)行分析總結(jié)出現(xiàn)的原因的總體原理當(dāng)中的數(shù)據(jù)預(yù)取在編寫代碼時(shí)候的限制的構(gòu)建原理出現(xiàn)的原因單頁(yè)應(yīng)用有一個(gè)很大的缺點(diǎn)就是問(wèn)題,搜索引擎目前只能對(duì)同步的進(jìn)
本文只是對(duì)Vue.js官方SSR文檔和對(duì)官方hackernews demo的個(gè)人學(xué)習(xí)總結(jié),說(shuō)得不夠完整的請(qǐng)見(jiàn)諒
本文主要對(duì)以下幾方面內(nèi)容對(duì)Vue.js SSR的內(nèi)容進(jìn)行分析總結(jié)
SSR出現(xiàn)的原因
Vue.js SSR的總體原理
SSR當(dāng)中的數(shù)據(jù)預(yù)取
SSR在編寫代碼時(shí)候的限制
SSR的webpack構(gòu)建原理
SSR出現(xiàn)的原因單頁(yè)應(yīng)用有一個(gè)很大的缺點(diǎn)就是SEO問(wèn)題,搜索引擎目前只能對(duì)同步的javascript進(jìn)行索引,但對(duì)于需要異步獲取數(shù)據(jù)的單頁(yè)應(yīng)用來(lái)說(shuō),搜索引擎并不會(huì)抓取到它們的內(nèi)容
更快的首屏內(nèi)容展示速度,單頁(yè)應(yīng)用需要等待JS文件加載完成,然后再進(jìn)行頁(yè)面渲染,而SSR是將渲染完畢的html傳輸給客戶端
Vue.js SSR的總體原理如果用一句話概括Vue.js SSR的運(yùn)作過(guò)程,那就是在服務(wù)端將Vue.js實(shí)例轉(zhuǎn)換成html字符串傳輸?shù)娇蛻舳耍缓筮M(jìn)行客戶端激活,使網(wǎng)頁(yè)內(nèi)容能在Vue實(shí)例的控制之下
這一句話包含兩步內(nèi)容
Vue.js實(shí)例轉(zhuǎn)換成html字符串
客戶端激活
先來(lái)看第一步
Vue.js應(yīng)用轉(zhuǎn)換成html字符串一個(gè)最簡(jiǎn)單的Vue.js單頁(yè)應(yīng)用是這樣的:
new Vue({ render: h => h("div", "123") }).$mount("#app")
這里也包含兩步
新建Vue實(shí)例
掛在到DOM上面
在服務(wù)端當(dāng)中我們不進(jìn)行上面第二步操作,取而代之的是將這個(gè)實(shí)例直接渲染成字符串,做這個(gè)工作的就是我們的vue-server-renderer
const renderer = require("vue-server-renderer").createRenderer() const Vue = require("vue") renderer.renderToString(new Vue({ render: h => h("div", 123) })).then(html => { console.log(html) }).catch(err => { console.error(err) }) // 輸出123
到現(xiàn)在一個(gè)最簡(jiǎn)單的vue ssr應(yīng)用在服務(wù)端的工作已經(jīng)完成了,下面我們轉(zhuǎn)向下一步客戶端激活
客戶端激活客戶端激活跟我們單頁(yè)應(yīng)用所做的工作相比,最大的不同點(diǎn)就是它并不會(huì)構(gòu)建DOM元素,只會(huì)對(duì)現(xiàn)有的DOM元素進(jìn)行激活,使它們能被Vue實(shí)例進(jìn)行控制,而判斷激活的關(guān)鍵就是上面的data-server-rendered屬性
至此,最簡(jiǎn)單的一個(gè)SSR應(yīng)用已經(jīng)構(gòu)建完成了,下面是對(duì)這個(gè)應(yīng)用的功能進(jìn)行進(jìn)一步的補(bǔ)充
SSR當(dāng)中的數(shù)據(jù)預(yù)取數(shù)據(jù)預(yù)取包含著兩個(gè)方面,客戶端的數(shù)據(jù)預(yù)取和服務(wù)端的數(shù)據(jù)預(yù)取
服務(wù)端的數(shù)據(jù)預(yù)取我們渲染一個(gè)內(nèi)容完整頁(yè)面的時(shí)候往往需要向服務(wù)器請(qǐng)求數(shù)據(jù),所以現(xiàn)在服務(wù)端的邏輯變成等待數(shù)據(jù)獲取完畢,然后將頁(yè)面轉(zhuǎn)換成html字符串
其中數(shù)據(jù)獲取有以下幾個(gè)問(wèn)題:
獲取哪些數(shù)據(jù)?
如何得到獲取數(shù)據(jù)的方法?
應(yīng)在何時(shí)預(yù)取數(shù)據(jù)?
預(yù)取的數(shù)據(jù)應(yīng)保存在哪里?
預(yù)取的數(shù)據(jù)應(yīng)該怎么樣跟客戶端進(jìn)行同步?
問(wèn)題1:
我們的數(shù)據(jù)用來(lái)渲染頁(yè)面,那么我們就需要組成當(dāng)前頁(yè)面的所有組件各自所需要的數(shù)據(jù)
問(wèn)題2:
每個(gè)需要進(jìn)行服務(wù)端數(shù)據(jù)預(yù)取的組件定義一個(gè)asyncData方法,此方法用于數(shù)據(jù)預(yù)取
問(wèn)題3:
我們需要先得到當(dāng)前頁(yè)面所有需要渲染的組件,然后再進(jìn)行數(shù)據(jù)預(yù)取
問(wèn)題4:
由于還需要進(jìn)行數(shù)據(jù)同步,所以很難將數(shù)據(jù)保存在組件的私有data上面,放在vuex上面是個(gè)普遍的選擇
問(wèn)題5:
服務(wù)端在返回html字符串的時(shí)候,store數(shù)據(jù)將被序列化以后以window.__INITIAL_STATE__=/* store state */的形式插入到腳本當(dāng)中被客戶端獲取,客戶端的store使用store.replaceState方法同步state
簡(jiǎn)單復(fù)述一下上面的流程就是:
在渲染當(dāng)前頁(yè)面的所有組件加載完畢以后,執(zhí)行這些組件的asyncData方法,這些方法將獲取到的數(shù)據(jù)將由vuex托管,獲取數(shù)據(jù)完畢以后即可將應(yīng)用渲染成html字符串,vuex store的state將會(huì)被序列化以后一并傳輸?shù)娇蛻舳?,被客戶端進(jìn)行同步
下面是實(shí)現(xiàn)的一些細(xì)節(jié):
判斷組件加載完畢的方法是vue-router的onReady方法
獲取當(dāng)前頁(yè)面的所有組件為vue-router的getMatchedComponents方法
由于源碼太長(zhǎng)所以沒(méi)貼出來(lái),具體可以到官網(wǎng)瀏覽
服務(wù)端數(shù)據(jù)預(yù)取的關(guān)鍵點(diǎn)算是總結(jié)的差不多了,下面簡(jiǎn)單說(shuō)一下客戶端的數(shù)據(jù)預(yù)取
客戶端數(shù)據(jù)預(yù)取客戶端的數(shù)據(jù)預(yù)取方法可分為兩種:
等待數(shù)據(jù)獲取完畢后再進(jìn)行視圖切換
先進(jìn)行視圖切換然后在進(jìn)行數(shù)據(jù)獲取
兩種方法區(qū)別在于讓用戶在什么時(shí)候產(chǎn)生等待的感覺(jué),第一種是在頁(yè)面切換時(shí),而第二種是在頁(yè)面切換完畢等待內(nèi)容的出現(xiàn)時(shí)
第一種方法的實(shí)現(xiàn)使用了vue-router實(shí)例的beforeResolve方法,這個(gè)方法執(zhí)行在異步組件加載完畢后,導(dǎo)航被確認(rèn)之前,當(dāng)完成數(shù)據(jù)預(yù)取以后router才會(huì)進(jìn)行DOM更新等步驟
第二種方法的實(shí)現(xiàn)跟我們一般進(jìn)行數(shù)據(jù)獲取一致,在beforeMount鉤子當(dāng)中執(zhí)行
SSR在編寫代碼時(shí)候的限制由于瀏覽器特定的API將會(huì)在服務(wù)端報(bào)錯(cuò),如"document"、"window"等,盡量避免使用此類API或者在非服務(wù)端運(yùn)行的聲明周期函數(shù)中調(diào)用如"mounted"等等
指令由于能直接操作DOM會(huì)受到很大的限制
SSR的webpack構(gòu)建原理以官方的hackernews demo為例,webpack有兩個(gè)入口entry-client和entry-server分別負(fù)責(zé)構(gòu)建客戶端和服務(wù)端的文件
服務(wù)端方面webpack會(huì)輸出一個(gè)名叫vue-ssr-server-bundle的json文件,此文件由官方提供的VueSSRServerPlugin插件所構(gòu)建而成,是服務(wù)端的構(gòu)建清單,傳入createBundleRenderer生成服務(wù)端渲染所需要的renderer
客戶端方面webpack輸出的是由代碼分割而成的chunk和公用bundle,與一般單頁(yè)應(yīng)用的構(gòu)建相似,不同的是會(huì)生成一個(gè)vue-ssr-client-manifest,此文件是客戶端方面的構(gòu)建清單,包含所有chunk的信息,將其傳入上面的renderer當(dāng)中能自動(dòng)將chunk嵌入到html當(dāng)中,當(dāng)然用戶也能夠取消,自行選擇手動(dòng)嵌入的內(nèi)容
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/105207.html
摘要:無(wú)需使用服務(wù)器實(shí)時(shí)動(dòng)態(tài)編譯,而是使用預(yù)渲染方式,在構(gòu)建時(shí)簡(jiǎn)單地生成針對(duì)特定路由的靜態(tài)文件。與可以部署在任何靜態(tài)文件服務(wù)器上的完全靜態(tài)單頁(yè)面應(yīng)用程序不同,服務(wù)器渲染應(yīng)用程序,需要處于運(yùn)行環(huán)境。更多的服務(wù)器端負(fù)載。 目錄結(jié)構(gòu) -no-ssr-demo 未做ssr之前的項(xiàng)目代碼用于對(duì)比 -vuecli2ssr 將vuecli生成的項(xiàng)目轉(zhuǎn)為ssr -prerender-demo 使用prer...
摘要:對(duì)于客戶端應(yīng)用來(lái)說(shuō),服務(wù)端渲染是一個(gè)熱門話題。在服務(wù)器預(yù)渲染初始應(yīng)用狀態(tài)。重構(gòu)這段腳本,使其可以在服務(wù)端運(yùn)行。如果這些原因和你的情況吻合,那么使用進(jìn)行服務(wù)端渲染將會(huì)是個(gè)不錯(cuò)方案。我已經(jīng)發(fā)布兩個(gè)庫(kù)來(lái)支持的服務(wù)端渲染和專為應(yīng)用打造的。 showImg(https://segmentfault.com/img/remote/1460000014155032);對(duì)于客戶端應(yīng)用來(lái)說(shuō),服務(wù)端渲染是...
摘要:好在后是支持服務(wù)端渲染的,零零散散花費(fèi)了兩三周事件,通過(guò)改造現(xiàn)有項(xiàng)目,基本完成了在現(xiàn)有項(xiàng)目中實(shí)踐了服務(wù)端渲染。在服務(wù)端生成對(duì)應(yīng)的字符串,客戶端接收到對(duì)應(yīng)的字符串,能立即渲染,最高效的首屏耗時(shí)。服務(wù)端渲染的原理是虛擬。實(shí)現(xiàn)前后端同構(gòu)應(yīng)用。 隨著各大前端框架的誕生和演變,SPA開(kāi)始流行,單頁(yè)面應(yīng)用的優(yōu)勢(shì)在于可以不重新加載整個(gè)頁(yè)面的情況下,通過(guò)ajax和服務(wù)器通信,實(shí)現(xiàn)整個(gè)Web應(yīng)用拒不更新...
閱讀 3145·2021-10-12 10:20
閱讀 2881·2021-09-27 13:56
閱讀 837·2021-09-27 13:36
閱讀 1462·2021-09-26 09:46
閱讀 2468·2019-08-30 14:02
閱讀 2715·2019-08-28 18:14
閱讀 1301·2019-08-26 10:32
閱讀 1732·2019-08-23 18:25