大公司裡怎樣開發和部署前端程式碼?

天府雲創發表於2017-12-07

這是一個非常有趣的 非主流前端領域,這個領域要探索的是如何用工程手段解決前端開發和部署優化的綜合問題,入行到現在一直在學習和實踐中。

在我的印象中,facebook是這個領域的鼻祖,有興趣、有梯子的同學可以去看看facebook的頁面原始碼,體會一下什麼叫工程化。

接下來,我想從原理展開講述,多圖,較長,希望能有耐心看完。

01.png

 

讓我們返璞歸真,從原始的前端開發講起。上圖是一個“可愛”的index.html頁面和它的樣式檔案a.css,用文字編輯器寫程式碼,無需編譯,本地預覽,確認OK,丟到伺服器,等待使用者訪問。前端就是這麼簡單,好好玩啊,門檻好低啊,分分鐘學會有木有!

02.png

 

然後我們訪問頁面,看到效果,再檢視一下網路請求,200!不錯,太™完美了!那麼,研發完成。。。。了麼?

等等,這還沒完呢!對於大公司來說,那些變態的訪問量和效能指標,將會讓前端一點也不“好玩”。

看看那個a.css的請求吧,如果每次使用者訪問頁面都要載入,是不是很影響效能,很浪費頻寬啊,我們希望最好這樣:

03.png

 

利用304,讓瀏覽器使用本地快取。但,這樣也就夠了嗎?不成!304叫協商快取,這玩意還是要和伺服器通訊一次,我們的優化級別是變態級,所以必須徹底滅掉這個請求,變成這樣:

04.png

 

強制瀏覽器使用本地快取(cache-control/expires),不要和伺服器通訊。好了,請求方面的優化已經達到變態級別,那問題來了:你都不讓瀏覽器發資源請求了,這快取咋更新?

很好,相信有人想到了辦法:通過更新頁面中引用的資源路徑,讓瀏覽器主動放棄快取,載入新資源。好像這樣:

05.png

 

下次上線,把連結地址改成新的版本,就更新資源了不是。OK,問題解決了麼?!當然沒有!大公司的變態又來了,思考這種情況:

06.png

 

頁面引用了3個css,而某次上線只改了其中的a.css,如果所有連結都更新版本,就會導致b.css,c.css的快取也失效,那豈不是又有浪費了?!

重新開啟變態模式,我們不難發現,要解決這種問題,必須讓url的修改與檔案內容關聯,也就是說,只有檔案內容變化,才會導致相應url的變更,從而實現檔案級別的精確快取控制。

什麼東西與檔案內容相關呢?我們會很自然的聯想到利用 資料摘要要演算法 對檔案求摘要資訊,摘要資訊與檔案內容一一對應,就有了一種可以精確到單個檔案粒度的快取控制依據了。好了,我們把url改成帶摘要資訊的:

07.png

 

這回再有檔案修改,就只更新那個檔案對應的url了,想到這裡貌似很完美了。你覺得這就夠了麼?大公司告訴你:圖樣圖森破!

唉~~~~,讓我喘口氣

現代網際網路企業,為了進一步提升網站效能,會把靜態資源和動態網頁分叢集部署,靜態資源會被部署到CDN節點上,網頁中引用的資源也會變成對應的部署路徑:

 

08.png

 

好了,當我要更新靜態資源的時候,同時也會更新html中的引用吧,就好像這樣:

09.png

 

這次釋出,同時改了頁面結構和樣式,也更新了靜態資源對應的url地址,現在要釋出程式碼上線,親愛的前端研發同學,你來告訴我,我們們是先上線頁面,還是先上線靜態資源?

先部署頁面,再部署資源:在二者部署的時間間隔內,如果有使用者訪問頁面,就會在新的頁面結構中載入舊的資源,並且把這個舊版本的資源當做新版本快取起來,其結果就是:使用者訪問到了一個樣式錯亂的頁面,除非手動重新整理,否則在資源快取過期之前,頁面會一直執行錯誤。

先部署資源,再部署頁面:在部署時間間隔之內,有舊版本資源本地快取的使用者訪問網站,由於請求的頁面是舊版本的,資源引用沒有改變,瀏覽器將直接使用本地快取,這種情況下頁面展現正常;但沒有本地快取或者快取過期的使用者訪問網站,就會出現舊版本頁面載入新版本資源的情況,導致頁面執行錯誤,但當頁面完成部署,這部分使用者再次訪問頁面又會恢復正常了。 好的,上面一坨分析想說的就是:先部署誰都不成!都會導致部署過程中發生頁面錯亂的問題。所以,訪問量不大的專案,可以讓研發同學苦逼一把,等到半夜偷偷上線,先上靜態資源,再部署頁面,看起來問題少一些。

但是,大公司超變態,沒有這樣的“絕對低峰期”,只有“相對低峰期”。So,為了穩定的服務,還得繼續追求極致啊!

這個奇葩問題,起源於資源的 覆蓋式釋出,用 待發布資源 覆蓋 已釋出資源,就有這種問題。解決它也好辦,就是實現 非覆蓋式釋出。

10.png

 

看上圖,用檔案的摘要資訊來對資原始檔進行重新命名,把摘要資訊放到資原始檔釋出路徑中,這樣,內容有修改的資源就變成了一個新的檔案釋出到線上,不會覆蓋已有的資原始檔。上線過程中,先全量部署靜態資源,再灰度部署頁面,整個問題就比較完美的解決了。

所以,大公司的靜態資源優化方案,基本上要實現這麼幾個東西:

配置超長時間的本地快取 —— 節省頻寬,提高效能

採用內容摘要作為快取更新依據 —— 精確的快取控制

靜態資源CDN部署 —— 優化網路請求

更資源釋出路徑實現非覆蓋式釋出 —— 平滑升級

全套做下來,就是相對比較完整的靜態資源快取控制方案了,而且,還要注意的是,靜態資源的快取控制要求在 前端所有靜態資源載入的位置都要做這樣的處理 。是的,所有!什麼js、css自不必說,還要包括js、css檔案中引用的資源路徑,由於涉及到摘要資訊,引用資源的摘要資訊也會引起引用檔案本身的內容改變,從而形成級聯的摘要變化,大概示意圖就是:

11.png

 

好了,目前我們快速的學習了一下前端工程中關於靜態資源快取要面臨的優化和部署問題,新的問題又來了:這™讓工程師怎麼寫碼啊!!!

要解釋優化與工程的結合處理思路,又會扯出一堆有關模組化開發、資源載入、請求合併、前端框架等等的工程問題,以上只是開了個頭,解決方案才是精髓,但要說的太多太多,有空再慢慢展開吧。

總之,前端效能優化絕逼是一個工程問題!

以上不是我YY的,可以觀察 百度 或者 facebook 的頁面以及靜態資源原始碼,檢視它們的資源引用路徑處理,以及網路請中靜態資源的快取控制部分。再次讚歎facebook的前端工程建設水平,跪舔了。

建議前端工程師多多關注前端工程領域,也許有人會覺得自己的產品很小,不用這麼變態,但很有可能說不定某天你就需要做出這樣的改變了。而且,如果我們能把事情做得更極致,為什麼不去做呢?

另外,也不要覺得這些是運維或者後端工程師要解決的問題。如果由其他角色來解決,大家總是把自己不關心的問題丟給別人,那麼前端工程師的開發過程將受到極大的限制,這種情況甚至在某些大公司都不少見!

媽媽,我再也不玩前端了。。。。5555

相關文章