先後端分離,目前對於一個前端開發者來講,或者將其放在軟件開發領域的歷史背景下,都是再日常不過的一件事情了。17 年時進行了一個先後端完全分離方案的實踐,每次想起來這個方案時,總以爲它不夠完美。如今將其寫下來和你們交流,指望能夠促進方案的後續完善。html
自從接觸前端開發,一共接觸到了三種前端項目發佈的方式:前端
剛加入丁香園前端團隊時,先後端分離的 SPA 項目的實現方式是:前端和服務端項目是兩個代碼倉庫,HTML 模板由服務端語言(JSP/PHP)輸出,HTML 引用的前端資源是經過前端資源發佈系統發佈到 cdn 上。涉及到 cdn,就會面臨 cdn 緩存的問題。解決 cdn 緩存問題的方案是傳統的時間戳機制。具體操做流程是服務端提供一個更新時間戳的接口,當前端每次發佈新版本後,去調用更新時間戳的接口。數據庫
基於時間戳機制的前端項目發佈流程大體爲:編程
看上去這個流程很簡單高效,對不對?讓咱們來根據實際狀況來細化一下這個流程:後端
流程細化以後,咱們能夠把流程分爲5步,平均算下來每次前端同窗進行一次項目發佈,大概須要3分鐘。在等待發布系統構建資源的時候,前端同窗能夠並行的去作一些放鬆的事情,好比:去餐吧喝杯咖啡,上個廁所,隨手修個 bug。放鬆以後,更新一下時間戳,新版本發佈便大功告成。接下來即可以進入愉悅的新需求開發之旅了,一切都顯得如此愜意。瀏覽器
去年的我,也是這樣認爲的。由於當時在負責的新版調查問卷(SPA)和 Insight(能夠看作 n 個 SPA)等項目,大概平均天天發佈一次,因此用來發布的時間成本仍是能接受的。緩存
16年年末時,加入了大衆醫學部,開始和夥伴們一塊兒負責來問丁香醫生等項目。項目依舊是先後端分離的 SPA,構建好的前端資源依舊是發佈到 cdn,解決 cdn 緩存問題一樣採用的是時間戳機制。一切都是熟悉的配方,熟悉的味道。當參與了一段時間的需求迭代後,我發現事情彷佛沒有想象的那麼簡單。服務器
讓我有這種感覺的緣由,主要有兩點:微信
此時細化的一次發佈流程變爲:網絡
一次前端發佈的時間,平均在7分鐘左右。在實際工做中,須要在測試環境、(預發環境)、生產環境進行發佈。從團隊的角度來看,管理後臺等項目也在採用這種發佈方式。毛估一下,每週團隊在項目發佈上就須要花費 2 ~ 3 個小時((7min * 2 * 2 * 5)/ 60)。
此外,這種先後端分離的方式還有如下幾個問題:
爲了解決上述問題,我設計了一個的方案:
方案說明:
方案肯定後,在團隊小夥伴的配合下,該方案在一個流量較小的項目上線了。
上述方案存在一個問題的:在原有的技術體系中,引入了 Node.js。本質上是在穩定的技術體系下,增長了技術複雜度。所以,在不增長技術複雜度的前提下,須要開始探索新的解決方案。在後端同窗的配合下,新方案相比於引入 Node.js 方案改動以下:
方案上線後,前端項目的發佈流程變爲:
前端項目發佈這件事,終於變成了點擊一下發布按鈕,整件事情就作好了。整個發佈流程耗時變爲不到一分鐘。此外,當前端須要改變 HTML 模板時,也再也不須要將文件發給後端同窗,苦苦等待後端項目的發版。
該方案上線後,組內同窗在週報中說起到的使用新方案後的感覺爲:
爲了方便前端同窗獲取同步模板的進展,在發佈系統中增長了同步過程的提醒:
上述方案相比於 JSP/PHP 提供 HTML 模板存在一個問題,就是在前端在構建 HTML 時,(暫時)不能將應用初始化的數據放入 HTML 中。解決方案是服務端提供一個接口,在應用啓動時去調用該接口獲取初始化數據。
對於前端加載優化,總體上思路上是須要減小網絡請求的,而此方案卻在增長網絡請求,這意味着頁面加載時間會變長。可是綜合利弊以後,仍是決定採用這個方案。
最終方案上線後,其實心中已經作好了頁面平均加載時間會變長的心理準備,可是有些意外的是,幾天後去 mta 看數據發現全國範圍內平均響應時間縮短了 0.2s 左右。爲何不升反降,目前我還不能得出一個準確的答案。猜想的一個緣由是: hash 值的方案避免了用戶進行沒必要要的資源更新。
上述方案雖然作到了前端項目的一鍵發佈,可是還不夠稱做爲一個完善的解決方案。由於該方案只是解決了 SPA 類型項目的發佈問題,對於以前「套模板」重 SEO 的項目而言,並非很適用。(提到 2018 年的技術浪潮下,如何開發一個重 SEO 的網站這個話題,又能夠寫一篇文章了,其中的心路歷程仍是蠻坎坷的)
言歸正傳,在前端資源發佈系統層面,該方案能夠考慮去增長文件歷史和發佈回滾功能,以備不時只需。
這個方案是和業務線的服務端同窗配合實現的,從公司層面來看,能夠考慮的點是是否能夠將這個方案作成一個通用的服務。
在和團隊的交流時,相學長提出能夠將 HTML 引用的資源抽象成 JSON Tree 進行存儲。以前看過一些相似的解決方案,不過目前本身仍是更傾向於分開的「更完全」,這樣可讓服務端同窗更安心的提供接口。
因爲水平有限,歡迎你們對此方案提出建議。很是期待。
本文做者:丁香園前端工程師 @志遙