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