大公司里怎樣開(kāi)發(fā)和部署前端代碼?

2018-02-24 15:49 更新

原文出處:https://github.com/fouber/blog/issues/6
作者:fouber

目錄

本文搬運(yùn)自我在知乎上?同名問(wèn)題?中的答案。

這是一個(gè)非常有趣的?非主流前端領(lǐng)域,這個(gè)領(lǐng)域要探索的是如何用工程手段解決前端開(kāi)發(fā)和部署優(yōu)化的綜合問(wèn)題,入行到現(xiàn)在一直在學(xué)習(xí)和實(shí)踐中。

在我的印象中,facebook是這個(gè)領(lǐng)域的鼻祖,有興趣、有梯子的同學(xué)可以去看看facebook的頁(yè)面源代碼,體會(huì)一下什么叫工程化。

接下來(lái),我想從原理展開(kāi)講述,多圖,較長(zhǎng),希望能有耐心看完。


簡(jiǎn)單頁(yè)面的網(wǎng)絡(luò)請(qǐng)求圖數(shù)據(jù)摘要要算法?對(duì)文件求摘要信息,摘要信息與文件內(nèi)容一一對(duì)應(yīng),就有了一種可以精確到單個(gè)文件粒度的緩存控制依據(jù)了。好了,我們把url改成帶摘要信息的:

使用摘要信息更新緩存

這回再有文件修改,就只更新那個(gè)文件對(duì)應(yīng)的url了,想到這里貌似很完美了。你覺(jué)得這就夠了么?大公司告訴你:圖樣圖森破!

唉~~~~,讓我喘口氣

現(xiàn)代互聯(lián)網(wǎng)企業(yè),為了進(jìn)一步提升網(wǎng)站性能,會(huì)把靜態(tài)資源和動(dòng)態(tài)網(wǎng)頁(yè)分集群部署,靜態(tài)資源會(huì)被部署到CDN節(jié)點(diǎn)上,網(wǎng)頁(yè)中引用的資源也會(huì)變成對(duì)應(yīng)的部署路徑:

靜態(tài)資源分集群部署

好了,當(dāng)我要更新靜態(tài)資源的時(shí)候,同時(shí)也會(huì)更新html中的引用吧,就好像這樣:

CDN部署過(guò)程

這次發(fā)布,同時(shí)改了頁(yè)面結(jié)構(gòu)和樣式,也更新了靜態(tài)資源對(duì)應(yīng)的url地址,現(xiàn)在要發(fā)布代碼上線,親愛(ài)的前端研發(fā)同學(xué),你來(lái)告訴我,咱們是先上線頁(yè)面,還是先上線靜態(tài)資源?

  1. 先部署頁(yè)面,再部署資源:在二者部署的時(shí)間間隔內(nèi),如果有用戶訪問(wèn)頁(yè)面,就會(huì)在新的頁(yè)面結(jié)構(gòu)中加載舊的資源,并且把這個(gè)舊版本的資源當(dāng)做新版本緩存起來(lái),其結(jié)果就是:用戶訪問(wèn)到了一個(gè)樣式錯(cuò)亂的頁(yè)面,除非手動(dòng)刷新,否則在資源緩存過(guò)期之前,頁(yè)面會(huì)一直執(zhí)行錯(cuò)誤。
  2. 先部署資源,再部署頁(yè)面:在部署時(shí)間間隔之內(nèi),有舊版本資源本地緩存的用戶訪問(wèn)網(wǎng)站,由于請(qǐng)求的頁(yè)面是舊版本的,資源引用沒(méi)有改變,瀏覽器將直接使用本地緩存,這種情況下頁(yè)面展現(xiàn)正常;但沒(méi)有本地緩存或者緩存過(guò)期的用戶訪問(wèn)網(wǎng)站,就會(huì)出現(xiàn)舊版本頁(yè)面加載新版本資源的情況,導(dǎo)致頁(yè)面執(zhí)行錯(cuò)誤,但當(dāng)頁(yè)面完成部署,這部分用戶再次訪問(wèn)頁(yè)面又會(huì)恢復(fù)正常了。 好的,上面一坨分析想說(shuō)的就是:先部署誰(shuí)都不成!都會(huì)導(dǎo)致部署過(guò)程中發(fā)生頁(yè)面錯(cuò)亂的問(wèn)題。所以,訪問(wèn)量不大的項(xiàng)目,可以讓研發(fā)同學(xué)苦逼一把,等到半夜偷偷上線,先上靜態(tài)資源,再部署頁(yè)面,看起來(lái)問(wèn)題少一些。

但是,大公司超變態(tài),沒(méi)有這樣的“絕對(duì)低峰期”,只有“相對(duì)低峰期”。So,為了穩(wěn)定的服務(wù),還得繼續(xù)追求極致啊!

這個(gè)奇葩問(wèn)題,起源于資源的 覆蓋式發(fā)布,用 待發(fā)布資源 覆蓋 已發(fā)布資源,就有這種問(wèn)題。解決它也好辦,就是實(shí)現(xiàn) 非覆蓋式發(fā)布。

非覆蓋式發(fā)布

看上圖,用文件的摘要信息來(lái)對(duì)資源文件進(jìn)行重命名,把摘要信息放到資源文件發(fā)布路徑中,這樣,內(nèi)容有修改的資源就變成了一個(gè)新的文件發(fā)布到線上,不會(huì)覆蓋已有的資源文件。上線過(guò)程中,先全量部署靜態(tài)資源,再灰度部署頁(yè)面,整個(gè)問(wèn)題就比較完美的解決了。

所以,大公司的靜態(tài)資源優(yōu)化方案,基本上要實(shí)現(xiàn)這么幾個(gè)東西:

  1. 配置超長(zhǎng)時(shí)間的本地緩存 —— 節(jié)省帶寬,提高性能
  2. 采用內(nèi)容摘要作為緩存更新依據(jù) —— 精確的緩存控制
  3. 靜態(tài)資源CDN部署 —— 優(yōu)化網(wǎng)絡(luò)請(qǐng)求
  4. 更資源發(fā)布路徑實(shí)現(xiàn)非覆蓋式發(fā)布 —— 平滑升級(jí)

全套做下來(lái),就是相對(duì)比較完整的靜態(tài)資源緩存控制方案了,而且,還要注意的是,靜態(tài)資源的緩存控制要求在?前端所有靜態(tài)資源加載的位置都要做這樣的處理?。是的,所有!什么js、css自不必說(shuō),還要包括js、css文件中引用的資源路徑,由于涉及到摘要信息,引用資源的摘要信息也會(huì)引起引用文件本身的內(nèi)容改變,從而形成級(jí)聯(lián)的摘要變化,大概示意圖就是:

多級(jí)依賴示意圖

好了,目前我們快速的學(xué)習(xí)了一下前端工程中關(guān)于靜態(tài)資源緩存要面臨的優(yōu)化和部署問(wèn)題,新的問(wèn)題又來(lái)了:這?讓工程師怎么寫(xiě)碼?。。。?/p>

要解釋優(yōu)化與工程的結(jié)合處理思路,又會(huì)扯出一堆有關(guān)模塊化開(kāi)發(fā)、資源加載、請(qǐng)求合并、前端框架等等的工程問(wèn)題,以上只是開(kāi)了個(gè)頭,解決方案才是精髓,但要說(shuō)的太多太多,有空再慢慢展開(kāi)吧。

總之,前端性能優(yōu)化絕逼是一個(gè)工程問(wèn)題!

以上不是我YY的,可以觀察 百度 或者 facebook 的頁(yè)面以及靜態(tài)資源源代碼,查看它們的資源引用路徑處理,以及網(wǎng)絡(luò)請(qǐng)中靜態(tài)資源的緩存控制部分。再次贊嘆facebook的前端工程建設(shè)水平,跪舔了。

建議前端工程師多多關(guān)注前端工程領(lǐng)域,也許有人會(huì)覺(jué)得自己的產(chǎn)品很小,不用這么變態(tài),但很有可能說(shuō)不定某天你就需要做出這樣的改變了。而且,如果我們能把事情做得更極致,為什么不去做呢?

另外,也不要覺(jué)得這些是運(yùn)維或者后端工程師要解決的問(wèn)題。如果由其他角色來(lái)解決,大家總是把自己不關(guān)心的問(wèn)題丟給別人,那么前端工程師的開(kāi)發(fā)過(guò)程將受到極大的限制,這種情況甚至在某些大公司都不少見(jiàn)!

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

業(yè)界實(shí)踐

Assets Pipeline

Rails中的Assets Pipeline完成了以上所說(shuō)的優(yōu)化細(xì)節(jié),對(duì)整個(gè)靜態(tài)資源的管理上的設(shè)計(jì)思考也是如此,了解rails的人也可以把此答案當(dāng)做是對(duì)rails中assets pipeline設(shè)計(jì)原理的分析。

rails通過(guò)把靜態(tài)資源變成erb模板文件,然后加入,上線前預(yù)編譯完成處理,fis的實(shí)現(xiàn)思路跟這個(gè)幾乎完全一樣,但我們當(dāng)初確實(shí)不知道有rails的這套方案存在。

相關(guān)資料:

FIS的解決方案

用 F.I.S 包裝了一個(gè)小工具,完整實(shí)現(xiàn)整個(gè)回答所說(shuō)的最佳部署方案,并提供了源碼對(duì)照,可以感受一下項(xiàng)目源碼和部署代碼的對(duì)照。

部署項(xiàng)目可以理解為線上發(fā)布后的結(jié)果,可以在部署項(xiàng)目里查看所有資源引用的md5化處理。

這個(gè)示例也可以用于和assets pipeline做比較。fis沒(méi)有assets的目錄規(guī)范約束,而且可以以獨(dú)立工具的方式組合各種前端開(kāi)發(fā)語(yǔ)言(coffee、less、sass/scss、stylus、markdown、jade、ejs、handlebars等等你能想到的),并與其他后端開(kāi)發(fā)語(yǔ)言結(jié)合。

assets pipeline的設(shè)計(jì)思想值得獨(dú)立成工具用于前端工程,fis就當(dāng)做這樣的一個(gè)選擇吧。

以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)