靜態資源緩存與更新

下圖是一個基本的index.html頁面和它的樣式文件a.csscss

 

放到服務器,訪問頁面網絡請求200大功告成。html

可是咱們思考一個問題,若是每次用戶訪問頁面都須要加載這個a.css的請求,很影響性能和浪費帶寬,咱們但願下面這個樣子前端

利用304讓瀏覽器使用本地緩存,考慮這樣是否有問題?有!304叫協商緩存,還須要和服務器通訊一次,因此要消除掉這個交互,變成這樣,算法

 

強制瀏覽器使用本地緩存(cache-control/expires), 再也不和服務器通訊。這個優化看起來已經很極致了。可是問題來了,不讓瀏覽器發資源請求,緩存如何更新呢?瀏覽器

相信你們都能想到這個辦法: 經過更新頁面中引用的資源路徑,讓瀏覽器主動放棄緩存,加載新資源,以下:緩存

下次上線,把資源地址改爲新的版本,資源就進行了更新,看起來沒什麼問題。考慮下下面這種狀況:服務器

頁面引用了三個css,而某次上線只改了其中的a.css。若是全部資源連接都更新版本,會致使b.css,c.css的緩存也生效,那樣就形成了帶寬浪費網絡

要解決這種問題,必須讓url的修改與文件內容關聯。也就是說,只有文件內容變化,纔會致使相應的url的變動,從而實現文件級別的精準緩存控制。性能

因此咱們天然聯想到了【數據摘要算法】對文件摘要,摘要信息與文件內容一一對應,就能夠把緩存控制到單個文件的粒度.優化

上面的url是帶摘要信息的,貌似很完美了。不過大公司中仍是 圖樣圖森破!

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

好了,那麼當咱們更新靜態資源的時候,一樣也會更新html中的資源引用,像下面這樣

此次發佈,同時改了頁面結構和樣式,也更新了靜態資源對應的url地址,如今要發佈代碼上線,親愛的前端研發同窗,我們是先上線頁面,仍是先上線靜態資源?

先部署頁面,再部署資源:在兩者部署的時間間隔內,若是有用戶訪問頁面,就會在新的頁面結構中加載舊的資源,而且把這個舊版本的資源當作新版本緩存起來,其結果就是:用戶訪問到了一個樣式錯亂的頁面,除非手動刷新,不然在資源緩存過時以前,頁面會一直執行錯誤。

先部署資源,再部署頁面:在部署時間間隔以內,有舊版本資源本地緩存的用戶訪問網站,因爲請求的頁面是舊版本的,資源引用沒有改變,瀏覽器將直接使用本地緩存,這種狀況下頁面展示正常;但沒有本地緩存或者緩存過時的用戶訪問網站,就會出現舊版本頁面加載新版本資源的狀況,致使頁面執行錯誤,但當頁面完成部署,這部分用戶再次訪問頁面又會恢復正常了。

好的,上面一坨分析想說的就是:先部署誰都不成!都會致使部署過程當中發生頁面錯亂的問題。因此,訪問量不大的項目,可讓研發同窗苦逼一把,等到半夜偷偷上線,先上靜態資源,再部署頁面,看起來問題少一些。

可是,大公司超變態,沒有這樣的「絕對低峯期」,只有「相對低峯期」。So,爲了穩定的服務,還得繼續追求極致啊!

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

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

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

1.配置超長時間的本地緩存 —— 節省帶寬,提升性能

2.採用內容摘要做爲緩存更新依據 —— 精確的緩存控制

3.靜態資源CDN部署 —— 優化網絡請求

4.更資源發佈路徑實現非覆蓋式發佈 —— 平滑升級

全套作下來,就是相對比較完整的靜態資源緩存控制方案了,並且,還要注意的是,靜態資源的緩存控制要求在 前端全部靜態資源加載的位置都要作這樣的處理 。是的,全部!什麼js、css自沒必要說,還要包括js、css文件中引用的資源路徑,因爲涉及到摘要信息,引用資源的摘要信息也會引發引用文件自己的內容改變,從而造成級聯的摘要變化,大概示意圖就是:

 

摘要hash和fis解決級聯資源定位能夠參看 http://www.infoq.com/cn/articles/front-end-engineering-and-performance-optimization-part1/ 

相關文章
相關標籤/搜索