hello~親愛的看官老爺們你們好~有一段時間沒寫文章了,最近忙於爲一個對內的數據可視化平臺進行徹底的先後端分離。原來的項目是一個基於 Vue
的單頁應用,重構後接入 Node
做爲中間層,達到徹底的先後端分離。前端
因爲項目相對簡單,成本並非過高。下文將簡單介紹一下使用的技術棧與分離後的收益,重點是對基於 Node
作先後端分離的一點思考。數據庫
大約是去年11月底入職新東家,接手一個僅 對內 的數據分析系統。新入職固然是但願作出點成績,在更改部分 UI 與優化部分功能以後,發現頁面性能仍是比較低。排查後發現獲取數據的接口沒有緩存,也不是基於 RESTful
的,瀏覽器緩存徹底不起做用。期間也經歷了後端修改接口,前端代碼大面積修改的狀況。json
基於後端同窗不熟悉前端機制,我也抱着方便往後搞事情的心態,在屢次滾地板以後,部門 Leader 贊成接入 Node
做爲中間層。後端
在肯定接入 Node
後,首先要作的就是技術選型。Node
通常就是在 Express
、Koa
與 Egg
中選。在中間件的使用上,我的偏好 Koa
,於是只好和 Express
說再見了 。Egg
是在 Koa
上做了強約束,規定代碼編寫、目錄結構等。瀏覽器
選型時我與前端 Leader 討論了無數次,他認爲 Egg
約束太多,擴展性較差,如若出現框架底層的 Bug 則難於處理,於是偏向於使用 Koa
。這樣的顧慮十分合理,然而對於如今的項目而言,不太可能有功能會超出 Egg
所提供的,反而 Egg
所提供的功能能爲項目搭建與維護減小很多的成本。至於約束,我的認爲這反而是一件好事,必定程度上解決了多人開發時代碼的組織問題。緩存
考慮再三後,決定使用 Egg
做爲 Node
的框架。安全
因爲項目不算十分複雜,接入的過程算是波瀾不驚。惟一的麻煩是工期比較緊,於是分兩步走:一期先接入 Node
,全部頁端請求原樣轉發 Java
,返回的結果原樣轉發頁端。二期對數據獲取的接口進行整合與優化以提高性能。完成後收益仍是客觀的,貼兩張圖展現下成果。數據結構
原來某頁面的性能(全部請求都是 Post 的):架構
接入 Node
相同頁面的性能(轉爲方法爲 Get):框架
能夠看到,不管是數據下載量仍是響應時間等指標,耗時均有下降。固然,這是創建在接入 Node
後我對接口進行了整合與緩存優化等措施後的對比。若是都是首次訪問,公司內網 WiFi 環境下與原來的性能會有稍差一點,總體加載時間略高於 Java
直出50ms不到。也用過 Chrome 模擬弱網環境,耗時與 Java
直出基本一致。
並且開發體驗上也比以前舒服得多,算是達到了接入 Node
前定下的目標:接入後在支持相同功能的狀況下性能提升30%;在相同的開發時間內,完成相同的需求,但有更好的開發體驗及更好的頁端性能。
小結一下,前端的一切優化都是在模板與獲取模板所需數據上進行優化,使用 Angular
、React
與 Vue
等框架構築的單頁應用,解決了模板的問題,能夠再也不讓後端去動咱們的模板。可是獲取所需數據仍依賴於後端,很多單頁應用交互上已經足夠複雜,若是還需維護一套複雜的獲取與整合數據的邏輯,仍是十分頭疼的。於是多接入一層 Node
處理數據的獲取與整合,盡最大努力去優化頁端的請求接口,讓頁端專一於交互,在條件成熟的狀況下,是十分值得的。
如若就爲了推廣 Node
,本文應該是把上面的步驟寫詳細,小結完就該結束了,這和不少大佬的實踐文章一致(固然我寫得不夠好~)。然而和兩位 Leader 的討論過程當中,感謝他們對 Node
技術抱有懷疑,提出了很多有意思的問題,結合我本身的思考,整理成提問形式呈現給你們。
爲什麼接入
Node
做爲中間層,和公司現行的PHP
有何區別?
沒有區別!事實說,Node
能作的 PHP
同樣能作。那麼問題就轉換爲 Node
的意義是什麼,爲什麼擯棄公司相對成熟的 PHP
方案而轉向 Node
?
我認爲後端服務主要是穩定爲主,業務調整不會特別頻繁。而對於前端而言,業務頻繁調整簡直司空見慣,若是先後端耦合在一塊兒,頻繁讓後端發版不是可取之策。同時,先後端對數據結構的要求及對其控制的粒度也大不相同。寫得好 PHP
的同窗不必定寫得好前端,寫得好前端的同窗不必定寫得好 PHP
。對於專業的領域,仍是應該由專業的人去作,讓前端控制整個模板及模板依賴的數據,對提升項目質量有很大的幫助。說句玩笑話,後端就搞搞數據庫,吐吐 json
就好,前端就拿一下數據,切切頁面就好。
進一步而言,前端若要接入 SSR
之類的功能,Node
還真比 PHP
有優點得多,也算是爲往後搞事情作鋪墊吧。
接入
Node
後性能會有多大提升?
不必定有提升,甚至有降低。此問題是我一期完成以後,測試頁端性能時發現的。測試時,Node
除了將全部的需求原樣轉發外,還加了協商緩存,然而響應時間卻更慢了。
接入前(爲 Post 請求):
接入後(爲 Get 請求):
正常來講,獲取 10k 左右的數據時,協商緩存如若命中即返回 304,省略了下載的過程,理應更快的。經過打點,發現 Node
轉發請求耗時額外增長 10ms 左右,然而在全公司內網 WiFi 環境下,總體下載時間不到 160ms。
於是引入 Node
不必定會有性能的提升,反而會由於多引入一層,而致使性能耗損。在對內的項目中或性能尚可的項目中,提升性能不足以成爲接入 Node
的關鍵理由。換句話說,接入 Node
以後,在優化頁端請求以前,並不可能爲應用性能帶來飛躍。
這個問題也算是我對 Node
態度轉變的起點,開始從無腦支持接入 Node
到辯證地推敲,也引出以後的的問題。
接入
Node
有什麼弊端?
前端的能力越強,意味着責任越多。例如以前多是 Java
作的安全防禦,可能就會下沉到 Node
端,這對大多數前端同窗而已都是比較陌生的領域。
投入的成本與產出也是值得商榷的事情,畢竟 Node
再貼近前端,也始終是屬於後端的領域。先後端思想不太同樣,用前端的思惟寫後端,極可能寫出十分糟糕的代碼,輕則影響性能,重則內存泄漏。接入 Node
層後它反而成爲拖累,相信你們也不肯看見。
畢竟 Node
對於很多公司而言是比較新的領域。儘管可能知道接入 Node
好處很多,但如何接入,接入後它能作什麼,你們可能比較模糊。如何花最少的代價,平滑地接入 Node
的同時,最大限度的複用現有架構,也是個很多的挑戰。
既然如此,沒有
Node
適用的場景嗎?
有。正如前文所說,Node
的意義是在於讓前端掌握模板與模板所依賴數據,不妨從這兩方面去進行考慮。如若重 SEO 的同時,頁面交互相對複雜,這時候接入 Node
做爲中間層,我認爲就是最佳實踐。
其次是後端架構不斷演變,開始轉向微服務化以後,前端感到接口碎片化開始帶來很多麻煩後,就應該考慮接入 Node
整合接口了。
總的來講,何時接入 Node
, 有點像何時引入 Redux
或 Vuex
。當你感受到麻煩後,只要你知道還有這個選項,天然而言地就會想到用它。
綜上所述,在如下場景中,我認爲接入 Node
是最佳實踐:
SSR
、PWA
等。如若只是性能問題,引入 Node
不必定會有改善,須要根據實際狀況進行分析。至於後端的接口設計太醜陋、返回的數據結構不符合前端使用等問題,在應用規模不大的狀況下,其實都是能夠和後端同窗進行溝通的,以此接入 Node
不必定是最佳的實踐,須要好好思量。
可是,堅定反對只是由於現有架構比較熟悉而不肯改變,始終抱着錯誤的方案不去解決的作法,這絕對是捨本逐末。我始終認爲,只要是對的事情,儘管過程再艱難,亦應該朝着對的方向前進。
以上是我的的一點淺見,感謝各位看官大人看到這裏。知易行難,但願本文對你有所幫助~謝謝!