摘要:所以,這次就來聊聊組件的服務(wù)器端渲染。這種模式下,后端只提供接口,傳統(tǒng)的服務(wù)器端路由模板渲染則都有層接管。這樣,前端開發(fā)人員可以自由的決定哪些組件需要在服務(wù)器端渲染,哪些組件可以放在客戶端渲染,前后端完全解耦,但又保留了服務(wù)器端渲染的功能。
細(xì)說 Vue 組件的服務(wù)器端渲染
聲明:需要讀者對(duì) NodeJs、Vue 服務(wù)器端渲染有一定的了解
現(xiàn)在,前后端分離與客戶端渲染已經(jīng)成為前端開發(fā)的主流模式,絕大部分的前端應(yīng)用都適合用這種方式來開發(fā),又特別是 React、Vue 等組件技術(shù)的發(fā)展,更是使這種方式深入人心。
但有一些應(yīng)用,客戶端渲染就會(huì)遇到一些問題了:
需要做 SEO(搜索引擎優(yōu)化),但客戶端渲染的 html 中幾乎沒有可用的信息
需要首屏快速加載,但客戶端渲染一般是長時(shí)間的加載動(dòng)畫或者白屏
如果能把客戶端渲染的組件化技術(shù)(React、Vue 等)與傳統(tǒng)的后端渲染的方式有效的結(jié)合起來,兩者兼具,那就太完美了。
所以,這次就來聊聊 Vue 組件的服務(wù)器端渲染。
根據(jù)社區(qū)現(xiàn)有的一些方案,結(jié)合自己的實(shí)踐,針對(duì)團(tuán)隊(duì)技術(shù)力量的不同,說說不同應(yīng)用場(chǎng)景選擇方案時(shí)的優(yōu)先級(jí)。
1. NodeJs 渲染中間層一般前后端的工作流是 后端 -> 前端。
傳統(tǒng)的后端渲染模式是后端負(fù)責(zé)包括 url、接口、模板渲染等,前端與后端耦合在一起,當(dāng)然這種方式正在慢慢的退出歷史舞臺(tái)。
主流的客戶端渲染則是后端只提供接口(如有需要,可以提供必要的 url),前端與后端只通過接口交流數(shù)據(jù),路由與渲染都在前端完成。
而 NodeJs 渲染中間層的工作流則是 后端 -> NodeJs -> 前端(NodeJs 渲染中間層由前端開發(fā)人員掌握)。
這種模式下,后端只提供接口,傳統(tǒng)的服務(wù)器端路由(url)、模板渲染則都有 NodeJs 層接管。這樣,前端開發(fā)人員可以自由的決定哪些組件需要在服務(wù)器端渲染,哪些組件可以放在客戶端渲染,前后端完全解耦,但又保留了服務(wù)器端渲染的功能。
這種方案最成熟的是 nuxt.js。
如果有需要,大家可以自己去 nuxt.js 官方文檔 看看具體的使用方法和詳細(xì)的功能。
應(yīng)該說,這種方式是目前最完美的一種方案,但也有一些隱患:
增加了一個(gè) NodeJs 中間層,應(yīng)用性能會(huì)有所降低
增加了架構(gòu)的復(fù)雜度、不穩(wěn)定性,也降低了應(yīng)用的安全性
對(duì)于高并發(fā)應(yīng)用,NodeJs 層會(huì)很容易形成瓶頸
對(duì)開發(fā)人員要求高了很多
所以,這種方式適合對(duì)并發(fā)量、安全性、穩(wěn)定性等要求不高,但又需要做 SEO 或首屏快速加載的頁面。
當(dāng)然,如果你能夠自己改造相關(guān)的工具,就另當(dāng)別論了。
2. 保留后端模板渲染當(dāng)不能使用 NodeJs 中間層時(shí),而又要達(dá)到 SEO 與首屏快速響應(yīng)的目的時(shí),在傳統(tǒng)的后端模板渲染的基礎(chǔ)上,就需要對(duì)前端的頁面加以適當(dāng)?shù)母脑臁?/p> 2.1 首屏快速響應(yīng)
首屏快速響應(yīng)就意味著首屏渲染所需的數(shù)據(jù)是跟 HTML 文件一起到達(dá)瀏覽器的,這些數(shù)據(jù)當(dāng)前是由后端模板引擎嵌入到 HTML 頁面中的。
以 Java 的 freemarker 模板引擎為例:
(html 中以 script 的方式獲取模板的數(shù)據(jù),這樣就算是在本地調(diào)試、開發(fā),也不會(huì)報(bào)錯(cuò))。
如果是復(fù)雜的 Json 數(shù)據(jù)或者其他復(fù)雜的模板數(shù)據(jù)(比如列表數(shù)據(jù)),則可以像下面這樣接收:
這樣,你就可以在組件里使用 window.globalData 的數(shù)據(jù)了,而不用另外用接口獲取數(shù)據(jù),達(dá)到加快首屏渲染的目的,而且本地開發(fā)、調(diào)試也不會(huì)報(bào)錯(cuò)。
如果你使用了本地?cái)?shù)據(jù) Mock 功能,也可以很容易的與這種方式結(jié)合在一起,只要稍加改造:
在代碼中定義本地和服務(wù)器兩個(gè)環(huán)境,本地環(huán)境使用 Mock 數(shù)據(jù),服務(wù)器環(huán)境使用 window.globalData
可以使用 see-ajax, see-fetch 來簡(jiǎn)化這種方式的開發(fā)
此外,還有一些措施來進(jìn)一步加快首屏渲染:
盡量減少首屏加載的腳本文件大小,其他腳本可以按需加載
如果需要,可以將 CSS、JS 內(nèi)容注入到 HTML 中,這樣就只會(huì)發(fā)起一個(gè)請(qǐng)求,也可以加快加載速度
2.2 SEO 優(yōu)化在上面加載首屏渲染的基礎(chǔ)上,對(duì)于 SEO 優(yōu)化也可以做相應(yīng)的改造。
其實(shí),在客戶端渲染已慢慢成為主流開發(fā)模式的同時(shí),搜索引擎也在跟進(jìn)這種變化。
截至目前,Google 和 Bing 可以很好對(duì)同步 JavaScript 應(yīng)用程序進(jìn)行索引,也就是說,即使是客戶端渲染,但只要是同步數(shù)據(jù)渲染(非 Ajax 獲取數(shù)據(jù),比如模板數(shù)據(jù)),搜索引擎也能抓取到相應(yīng)的 HTML 片段。
(國內(nèi)的百度搜索與360搜索等暫時(shí)還沒有跟進(jìn)動(dòng)態(tài))
但為了兼容所有的搜索引擎,可以像下面改造:
先由后端模板引擎渲染一些 HTML 片段,僅給搜索引擎抓取,不作為給用戶展示的頁面
然后再由客戶端渲染同步或異步的數(shù)據(jù)給用戶展示真正的頁面
3. 導(dǎo)出靜態(tài) html
如果頁面沒有動(dòng)態(tài)數(shù)據(jù),那就好辦了,直接把組件導(dǎo)出為靜態(tài) html,然后由客戶端激活。
具體過程可以參考 官方文檔。
這種方案比較好的是 nuxt.js generate 靜態(tài) HTML 文件。
目錄結(jié)構(gòu):
- pages/ # 頁面結(jié)構(gòu)目錄 - index.vue - second.vue - ... - nuxt.config.js # 配置文件 - package.json - dist # 導(dǎo)出靜態(tài) HTML 文件的默認(rèn)目錄
導(dǎo)出靜態(tài) HTML 文件
npx nuxt generate
如果一個(gè)項(xiàng)目里有多個(gè) pages,可以這樣構(gòu)建:
目錄結(jié)構(gòu):
- nuxt.config.js # 配置文件 - package.json - src/ - home/ # home 頁面 - pages/ # 頁面結(jié)構(gòu)目錄 - index.vue - second.vue - ... - dist # 導(dǎo)出靜態(tài) HTML 文件的默認(rèn)目錄 - about/ # about 頁面 - pages/ # 頁面結(jié)構(gòu)目錄 - index.vue - second.vue - ... - dist # 導(dǎo)出靜態(tài) HTML 文件的默認(rèn)目錄
導(dǎo)出靜態(tài) HTML 文件
npx nuxt generate src/home -c ../../nuxt.config.js # home 頁面 npx nuxt generate src/about -c ../../nuxt.config.js # about 頁面
除了上面提到的這些方式外,當(dāng)然還有其他的方式,比如:
使用 Chrome Headless 模式獲取組件的靜態(tài) HTML,參考 react-snap, puppeteer
官方 vue-server-renderer 導(dǎo)出靜態(tài) HTML
4. 總結(jié)因?yàn)槟J降母淖?,服?wù)器端渲染與傳統(tǒng)的后端模板渲染工作方式有很大的不同,所以在開發(fā)時(shí)需要與后端開發(fā)人員做好溝通,避免認(rèn)知上的不同導(dǎo)致協(xié)作不協(xié)調(diào)。
后續(xù)更多博客,查看 https://github.com/senntyou/blogs
作者:深予之 (@senntyou)
版權(quán)聲明:自由轉(zhuǎn)載-非商用-非衍生-保持署名(創(chuàng)意共享3.0許可證)
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/104264.html
摘要:細(xì)說后端模板渲染客戶端渲染中間層服務(wù)器端渲染前端與后端渲染方式的發(fā)展大致經(jīng)歷了這樣幾個(gè)階段后端模板渲染客戶端渲染中間層服務(wù)器端渲染。與后端模板渲染剛好相反,客戶端渲染的頁面渲染都是在客戶端進(jìn)行,后端不負(fù)責(zé)任何的渲染,只管數(shù)據(jù)交互。 細(xì)說后端模板渲染、客戶端渲染、node 中間層、服務(wù)器端渲染(ssr) 前端與后端渲染方式的發(fā)展大致經(jīng)歷了這樣幾個(gè)階段:后端模板渲染、客戶端渲染、node ...
摘要:有目錄結(jié)構(gòu)書寫方式組件集成項(xiàng)目構(gòu)建等的約束,整個(gè)應(yīng)用中是沒有文件的,所有的響應(yīng)都是動(dòng)態(tài)渲染的,包括里面的元信息路徑等。更多參考細(xì)說后端模板渲染客戶端渲染中間層服務(wù)器端渲染開發(fā)工具開發(fā)時(shí)主要會(huì)用到的工具。 vue 前端項(xiàng)目技術(shù)選型、開發(fā)工具、周邊生態(tài) 聲明:這不是一篇介紹 Vue 基礎(chǔ)知識(shí)的文章,需要熟悉 Vue 相關(guān)知識(shí) 主架構(gòu):vue, vue-router, vuex UI 框...
摘要:有目錄結(jié)構(gòu)書寫方式組件集成項(xiàng)目構(gòu)建等的約束,整個(gè)應(yīng)用中是沒有文件的,所有的響應(yīng)都是動(dòng)態(tài)渲染的,包括里面的元信息路徑等。更多參考細(xì)說后端模板渲染客戶端渲染中間層服務(wù)器端渲染開發(fā)工具開發(fā)時(shí)主要會(huì)用到的工具。 vue 前端項(xiàng)目技術(shù)選型、開發(fā)工具、周邊生態(tài) 聲明:這不是一篇介紹 Vue 基礎(chǔ)知識(shí)的文章,需要熟悉 Vue 相關(guān)知識(shí) 主架構(gòu):vue, vue-router, vuex UI 框...
摘要:,常規(guī)組件,卒。小結(jié)總之呢,上面分析了在中編譯遠(yuǎn)程模板的可能性,最后得出了兩種方法異步組件,應(yīng)該是官方的推薦方法動(dòng)態(tài)組件,變通之法,論壇上發(fā)現(xiàn)的思路當(dāng)然如果有其他方法歡迎交流,本文如果有不嚴(yán)謹(jǐn)不正確的地方也歡迎指出本文發(fā)自我的,原文鏈接我的 說明 有些時(shí)候你可能需要從后臺(tái)獲取模板,并在前臺(tái)在自己編譯,這在用 AngularJS 1.x 的時(shí)候似乎很常見,可以直接用 ng-include...
摘要:,常規(guī)組件,卒。小結(jié)總之呢,上面分析了在中編譯遠(yuǎn)程模板的可能性,最后得出了兩種方法異步組件,應(yīng)該是官方的推薦方法動(dòng)態(tài)組件,變通之法,論壇上發(fā)現(xiàn)的思路當(dāng)然如果有其他方法歡迎交流,本文如果有不嚴(yán)謹(jǐn)不正確的地方也歡迎指出本文發(fā)自我的,原文鏈接我的 說明 有些時(shí)候你可能需要從后臺(tái)獲取模板,并在前臺(tái)在自己編譯,這在用 AngularJS 1.x 的時(shí)候似乎很常見,可以直接用 ng-include...
閱讀 1778·2023-04-25 23:43
閱讀 962·2021-11-24 09:39
閱讀 744·2021-11-22 15:25
閱讀 1744·2021-11-22 12:08
閱讀 1118·2021-11-18 10:07
閱讀 2103·2021-09-23 11:22
閱讀 3374·2021-09-22 15:23
閱讀 2608·2021-09-13 10:32