前言
在做前後端分離時,第一個關注的問題就是 渲染,也就是 View 這個層面的工作。
在傳統的開發模式中,瀏覽器端與伺服器端是由不同的前後端兩個團隊開發,但是模版卻又在這兩者中間的模糊地帶。因此模版上面總是不可避免的越來越複雜邏輯,最終難以維護。
而我們選擇了NodeJS,作為一個前後端的中間層。試著藉由NodeJS,來疏理 View 層面的工作。
讓前後端分工更明確,讓專案更好維護,達成更好的使用者體驗。
本文
渲染這塊工作,對於前端開發者的日常工作來說,佔了非常大的比例,也是最容易與後端開發糾結不清的地方。
回首過去前端科技發展的這幾年, View 這個層面的工作,經過了許多次的變革,像是:
Form Submit 全頁刷新 => AJAX局部刷新
服務端續染 MVC => 客戶端渲染 MVC
傳統換頁跳轉 => 單頁應用程式
可以觀察到在這幾年,大家都傾向將 渲染 這件事,從伺服器端端移向了瀏覽器端。
而伺服器端則專注於 服務化 ,提供資料介面。
瀏覽器端渲染的好處
瀏覽器端渲染的好處,我們都很清楚,像是
1.擺脫業務邏輯與呈現邏輯在Java模版引擎中的耦合與混亂。
2.針對多終端應用,更容易以介面化的形式。在瀏覽器端搭配不同的模版,呈現不同的應用。
3.頁面呈現本來就不只是html,在前端的渲染可以更輕易的以元件化形式 (html js css)提供功能,使得前端元件不依賴服務端產生的html結構。
4.脫離對於後端開發、發布流程的依賴。
5.方便聯調。
瀏覽器端渲染造成的壞處
但是在享受好處的同時,我們同樣的也面臨了 瀏覽器端渲染 所帶來的壞處,像是:
1.模版分離在不同的庫。有的模版放在服務端 (JAVA),而有的則放在瀏覽器端 (JS)。前後端模版語言不相通。
2.需要等待所有模版與元件在瀏覽器端載入完成後才能開始渲染,無法即開即看。
3.首次進入會有白屏等待渲染的時間,不利於使用者體驗
4.開發單一頁面應用程式時,前端Route與伺服器端Route不匹配,處理起來很麻煩。
5.重要內容都在前端組裝,不利於SEO
反思前後端的定義
其實回頭想想,在我們把渲染的工作從服務端(Java) 抽出來到瀏覽器端(JS) 的時候,我們的目的只是明確的前後端職責劃分,並不是非瀏覽器渲染不可。
只是因為在傳統的開發模式中,出了伺服器就到了瀏覽器,所以前端的工作內容只能被限制在瀏覽器端。
也因此很多人認定了 後端 = 服務端 前端 = 瀏覽器端 ,就像下面這張圖。
而在淘寶UED目前進行的中途島Midway 專案中,藉由在JAVA – Browser中間搭建一個NodeJS中間層,試圖把這個前後端的分割線,重新針對工作職責去區分,而非針對硬體環境去區分(伺服器& 瀏覽器)。
因此我們有機會做到模版與路由的共享,也是一個前後端分工中最理想的狀態。
淘寶中途島 Midway
在中途島專案中,我們把前後端分界的那條線,從瀏覽器端移回了伺服器端。
藉由一個由前端 輕鬆掌控 且 與瀏覽器共通 的Nodejs層,可以更清晰的完成了前後端分離。
也可以讓前端開發針對不同的情況,自行決定 最適當的解決方案 。而不是所有事情 都在瀏覽器端來處理 。
職責劃分
中途島並不是前端試圖搶後端飯碗的項目,目的只是把 模版 這個模糊地帶切割清楚,取得更明確的職責劃分。
後端 (JAVA),專注於
1.服務層
2.資料格式、資料穩定度
3.業務邏輯
前端,專注於
1.UI層
2.控制邏輯、渲染邏輯
3.互動、使用者體驗
而不再拘泥於服務端或瀏覽器端的差異。
模版分享
在傳統的開發模式中,瀏覽器端與伺服器端是由不同的前後端兩個團隊開發,但是模版卻又在這兩者中間的模糊地帶。因此模版上面總是不可避免的越來越複雜邏輯,最終難以維護。
有了NodeJS,後端同學可以在JAVA層專注於商業邏輯與資料的開發。而前端同學則專注於控制邏輯與渲染的開發。並且自行選擇這些模版是要在 服務端 (NodeJS) 或是 瀏覽器端 做渲染。
用相同的模版語言 XTemplate ,一樣的渲染引擎 JavaScript
在 不同的渲染環境 (Server-side、PC Browser、Mobile Browser、Web View、etc.) 渲染出 一樣的結果 。
路由共享
也因為有了NodeJS這一層,可以更細緻的控制路由。
假如需要在前端做瀏覽器端路由時,可以同時配置伺服器端的路由,使其在 瀏覽器端換頁 或是 服務端換頁 ,都可以得到一致的渲染效果。
同時也處理了SEO的問題。
模版共享的實踐
通常我們在瀏覽器端渲染一份模版時,流程不外乎是
在瀏覽器端載入模版引擎 (xtmpleate, juicer, handlerbar, etc.)
在瀏覽器端載入模版檔案,方法可能有
使用 印在頁面上
使用模組載入工具,載入模版檔案 (KISSY, requireJS, etc.)
其他
取得數據,使用模版引擎產生html
將html插入到指定位置。
從以上的流程可以觀察到,要想要做到模版的跨端共享,重點其實在 一致的模組選型 這件事。
市面上流行很多種模組標準,例如 KMD、AMD、CommonJS,只要能將NodeJS的模版檔案透過一致模組規範輸出到NodeJS端,就可以做基本的模版共享了。
而後續的系列文章會針對Model的proxy與分享,做進一步的探討。
個案探討
因為有了中途島這中間層,針對過往的一些問題都有了更好的解答,例如說
案例一 複雜互動應用 (如購物車、下單頁)
狀況:全部的HTML都是在前端渲染完成,服務端只提供介面。
問題:進入頁面時,會有短暫白屏。
解答:
首次進入頁面,在NodeJS端進行 全頁渲染 ,並在背景下載相關的模版。
後續互動操作,在瀏覽器端完成 局部刷新
用的是 同一份模版 , 產生 一樣的結果
案例二 單頁應用
狀況:使用Client Side MVC框架,在瀏覽器換頁。
問題:渲染與換頁都在瀏覽器端完成,直接輸入網址進入或f5刷新時,無法直接呈現相同的內容。
解答:
在瀏覽器端與NodeJS端共用 同樣的Route 設定
瀏覽器端換頁時,在瀏覽器端進行Route變更與 頁面內容渲染
直接輸入相同的網址時,在NodeJS端進行 頁面框架 頁面內容渲染
不管是瀏覽器端換頁,或直接輸入同樣的網址,看到的內容都是 一樣的 。
除了增加體驗、減少邏輯複雜度。更解決了 SEO 的問題
案例三 純瀏覽型頁面
狀況:頁面僅提供資訊,較少或沒有互動
問題:html在服務端產生,css與js放在另一個位置,彼此間有依賴。
解答:
透過NodeJS,統一管理html css js
日後若需要擴展成複雜應用或是單頁應用,也可以輕易轉移。
案例四 跨終端頁
狀況:同樣的應用要在不同端點呈現不同的介面與互動
問題:html管理不易,常常在服務端產生不一樣的html,瀏覽器端又要做不一樣的處理
解答:
跨終端的頁面是渲染的問題,統一由前端來處理。
透過NodeJS層與後端服務化,可以針對這類型複雜應用,設計最佳的解決方案。
總結
過去的AJAX、Client-side MVC、SPA、Two-way Data Binding 等技術的出現,都是試圖解決當時的前端開發遇到的瓶頸。
而NodeJS中間層的出現,也是在試圖解決現今前端被局限在瀏覽器端的一個限制。
這邊文章專注於前後端模版共享,也希望能拋磚引玉,與大家一起討論如何在NodeJS中間層這個架構下,我們可以怎樣的改善我們的工作流程,怎樣的跟後端配合,來把前端這個工作做得更好。