最近1年多,前后端同構慢慢變成一個(gè)流行詞,也許很多人還停留在前后端分離的最佳實(shí)踐道路上,但實(shí)際上又有一批人已經(jīng)從簡(jiǎn)單的服務(wù)端渲染走向探索最佳前后端同構方案的路上了。不過(guò),我只是膜拜后者的過(guò)客。
雖然大家可以去網(wǎng)絡(luò )搜索一下相關(guān)的概念解釋?zhuān)@里我還是簡(jiǎn)單列舉一下,我理解的術(shù)語(yǔ)。
1、前端渲染:瀏覽器一側使用js,借助模版或vue、react、angular等框架做的DOM結構生成。
2、后端渲染:服務(wù)器一側,使用php、nodejs等技術(shù)實(shí)現DOM結構生成,并在HTTP請求中返回給瀏覽器。
3、同構:瀏覽器一側的JS、HTML和服務(wù)器一側使用的JS、HTML使用同樣的開(kāi)發(fā)結構,同樣的開(kāi)發(fā)思路,同樣的開(kāi)發(fā)模式,盡可能實(shí)現代碼復用。
明確一點(diǎn),作為有追求的前端開(kāi)發(fā),我們不應該盲目跟風(fēng),一切需要從實(shí)際出發(fā)。
那么,首先,我們需要了解為什么會(huì )有同構這個(gè)概念出現。
百度搜一下前后端同構,清一色的vue、react。這些確實(shí)是同構,但我認為范圍太窄,同構不是框架帶來(lái)的問(wèn)題,而是因為前后端獨立渲染這種架構層面帶來(lái)的問(wèn)題。
當然,那些同構探討也是非常有價(jià)值的,但不在本文的討論范圍內,在這里我更想表達一下,如何從實(shí)際項目需求的角度來(lái)看,找出自己所需的同構之道。
畢竟,要知道,同構不是為了跟風(fēng)???,也不是為了跳槽面試的時(shí)候博點(diǎn)好感。同構,是為了提高用戶(hù)體驗的同時(shí),提高團隊的工作效率。
接下來(lái),我想根據項目的類(lèi)型,說(shuō)說(shuō)自己的看法。
第一種,單頁(yè)面應用。
這個(gè)網(wǎng)站很類(lèi)似一個(gè)APP,確實(shí)很有必要做成單頁(yè)應用,有助于提高用戶(hù)體驗。
如果第一步選擇了單頁(yè)面應用,這里就衍生了另外的問(wèn)題——SEO。而react等框架做了服務(wù)器渲染,最大目的其實(shí)也是解決SEO。
既然瀏覽器端選擇了某個(gè)框架,例如React,而同時(shí)又考慮nodejs直出提高首屏的速度,那么就沒(méi)有討價(jià)還價(jià)的余地了,當然上react全家桶,前后端都用react。
這一種情況,也就是網(wǎng)上搜索到的各種文章的情況。
第二種,多頁(yè)面純數據展示,每一頁(yè)都比較簡(jiǎn)單,沒(méi)有分屏的必要。
如果項目是這樣的情況,使用nodejs直出,無(wú)非就是提高打開(kāi)速度。而前后端基本八竿子打不著(zhù),最多就是一些工具函數(轉換一下日期格式,輸入框校驗)要做復用。
此時(shí),沒(méi)必要大費周折去考慮什么框架,因地制宜,想想自己需要什么即可。
要解決函數庫的前后端復用,可以簡(jiǎn)單做commonjs/window的兼容。
如果瀏覽器端的代碼比較多,就可以考慮粒度化,使用webpack做瀏覽器端代碼打包,同時(shí)commonjs的寫(xiě)法也可以復用到nodejs層。
第三種,多頁(yè)面而且每一頁(yè)不是那么簡(jiǎn)單,首屏和次屏有一些HTML片段(模版)需要復用
之前我所在項目組也遇到這樣的情況,怎么處理,一時(shí)之間為了趕進(jìn)度也沒(méi)太多考慮,使用了一些旁門(mén)左道,不好理解不好維護的方式,基于art-template做了一套有點(diǎn)奇怪的代碼,基本沒(méi)有同構一說(shuō)。唯一同構的就是art-template支持瀏覽器和nodejs。
情況怎么惡心呢?大概是這樣:
回頭想想,當時(shí)情況確實(shí)很糟,其實(shí)可以利用已有的工具做得更優(yōu)。
art-template是個(gè)好東西,這個(gè)沒(méi)必要去除。剛說(shuō)的前兩點(diǎn),表明這個(gè)項目有強烈的前后端代碼復用的必要,很有需要使用更全面的同構方案。
現在我覺(jué)得有更好的方式:
引入了webpack到瀏覽器端,就能很好的解決了原先html模版傳播的尷尬。而模塊風(fēng)格的統一,也有利于前后端代碼更好的復用。
至于最終瀏覽器js是否打包到首屏HTML中,還是單獨的部署CDN,這個(gè)其實(shí)就不是同構的問(wèn)題了。不過(guò)對于移動(dòng)端而言,還是建議合并在一起。
抽象一下,對于第三種項目情況,跳出我原先的項目。我認為,關(guān)鍵是要把前后端使用的模版統一為一個(gè)方式引入。
第四種,還是多頁(yè)面,瀏覽器端沒(méi)有模版拼裝的需求,第三種情況的變種。
或者說(shuō),這個(gè)不是一個(gè)單獨的項目情況,只是因為用的技術(shù)方案不同。跟第三種情況一樣,但次屏的渲染,我們不在瀏覽器端執行,而是繼續交給nodejs。瀏覽器端通過(guò)ajax把次屏html片段拉取回來(lái),然后直接塞到body中。而且,除此之外,瀏覽器端沒(méi)有用戶(hù)交互會(huì )導致已有的DOM發(fā)生重繪,或者極少內容重繪,不需要動(dòng)用到模版。
在這個(gè)情況下,瀏覽器端js更純粹的只關(guān)注事件處理。
我覺(jué)得這個(gè)又回到了第二種情況,只需要簡(jiǎn)單把一些庫函數封裝一下,做成前后端共用即可。
第四種情況,因為徹底拋棄了瀏覽器渲染,整個(gè)情況就簡(jiǎn)單多了,不需要考慮模版和很多邏輯js的前后端復用問(wèn)題。
聯(lián)系客服