在8年以前,Yahoo團隊曾經對網頁中的緩存作了比較詳盡的研究,可是隨着互聯網的高速發展,研究數據發生了一些變化。這篇文章主要是Facebook的web團隊對如今緩存狀況一些數據收集和研究。包括PC和移動端資源被緩存的時間以及資源在存在的時間。網頁緩存是性能優化很重要的因素,值得一讀。 jquery
能力有限,若有翻譯錯誤的地方,歡迎隨時找我交流,我會及時更正:)android
網頁加載速度是每一個網站都應該重視的因素。可是每每被你們忽略。緩存是一個提高網站訪問速度很是重要的因素(由於用戶在下次訪問的時候不須要從新計算或者下載已經緩存的資源)web
咱們團隊(facebook web團隊)最近針對目前facebook.com沒有緩存的現狀進行了一番討論,主要問題是:在facebook,.咱們天天都會發布兩個版本,怎麼樣才能令緩存更有效率?怎麼樣的緩存策略才適合咱們?chrome
在找解決方案的時候, 咱們發現雅虎性能優化研究博客上已經有了一篇關於性能研究的文章。數據庫
可是令咱們很是吃驚的是:20%的頁面訪問是在空緩存的狀況下進行的。可是這個研究結果距離如今有8年了,那個時代剛發佈IE7,jquery也剛發佈第一個版本,因此咱們決定從新研究一下,看如今是否是有所改善。瀏覽器
在以前的研究當中,Yahoo在服務器建立了HTTP頭設置了圖片的過時時間和上次修改時間,若是圖片沒有發生改變,就用GET請求發送給服務器一個最後修改時間的信息,若是圖片沒有修改,就返回304(沒有修改)來替換200(請求成功)。由於服務器能夠記錄瀏覽器請求的請求狀態,因此Yahoo用服務器日誌來統計緩存的用戶數。緩存
像那樣的研究方法同樣,咱們建立了一個既能發送圖片請求也能在數據庫當中記錄日誌的PHP終點。這張圖片用http頭信息來控制瀏覽器的緩存和其餘經過代理產生的緩存。以後在用戶請求圖片的時候記錄這些信息。性能優化
這個圖片HTTP頭信息的設置是這樣的:服務器
可是由於一些已知的BUG,咱們在IE7和IE8中把兩個屬性替換成了下面這樣:ide
當瀏覽器發送請求給圖片時候,將會發生兩件事情:
1。由於瀏覽器歷來沒有打開過這張圖片,因此沒有額外的頭信息,服務器將返回一個狀態碼:200 Success 接着返回圖片數據給瀏覽器,以後瀏覽器會緩存文件的HTTP頭信息當中的Last-Modified(文件最後修改時間)和ETag(被請求變量的實體值)
2。瀏覽器檢查if-none-match或者if-modified-since頭信息,若是以前有打開過。將會不加載圖片數據直接返回Status:304 Not Modified(沒有更新)。同時咱們把Last-Moidified頭信息用$header['if-modified-since']替換掉$now(),因此每次返回的內容都將是同樣的。
如今剩下問題是咱們在哪裏應用這張圖片,最後咱們決定在Facebook的搜索條下面包含一個img標籤,這樣每次facebook加載的時候都會渲染這張圖片。在整個頁面從新加載的時候,資源將會根據緩存的頭信息進行加載。這將是最好的方式來測試咱們的想法。
在確保endpoint能夠正常記錄請求、圖片標籤能夠正常訪問了以後,咱們正式開始了此次研究!
在數週的數據收集以後,咱們決定來研究一下7天最後比較有價值的數據。數據的統計結果依舊讓咱們感到吃驚:依舊有25.5%的請求是空緩存的。爲了讓數據看起來更清晰,咱們分隔了PC和手機的統計數據,可是數據依舊差很少:PC有24.8%而手機端有26.9%是空緩存的。這個結果不太符合咱們預期,因此咱們更加深刻的研究了這個數據。
把PC端的瀏覽器分開來統計可能更加清楚:
根據上面一週的數據來看:用戶用chrome和opera緩存的概率更大。你可能注意到你這個圖表中並無firefox瀏覽器的數據,那是由於firefox 31版本以及更早期的版本在咱們的統計中有80%的緩存機率,可是在32版本和更高的版本當中有很明顯的降低。那是由於firefox的緩存策略和咱們的統計方法有點衝突(http://www.janbambas.cz/new-firefox-http-cache-enabled/),
因此咱們就乾脆去掉了firefox瀏覽器的數據統計。
好了,如今讓咱們來看看移動端的數據:
能夠看到,大部分瀏覽器的緩存比例是在68%和84%之間。移動平臺的數據差異仍是挺大的,咱們想可能都是比較低端的移動設備(https://code.facebook.com/posts/307478339448736/year-class-a-classification-system-for-android/)。除此之外數據跟桌面端仍是比較類似的。
下面這個圖分別是移動端和手機端空緩存用戶所佔的比例:
平均來看,有44.6%的用戶是空緩存的,這個也很符合Yahoo團隊在2007年作的研究。
到這裏,文章尚未完結。在Facebook,咱們迭代速度很是快,天天幾乎都會發布兩個版本。這個驅動咱們去思考,多長時間的緩存設置適合咱們呢?咱們將if-modified-since這個文件頭返回的時間減去當前時間來尋找答案。
因此咱們根據上面的方法,咱們統計了從第一次正常請求到發生304請求的時間(這說明了用戶從沒有緩存到有緩存經歷了多長時間),下面是數據生成的圖標:
橫軸是以小時爲單位的時間值,垂直豎線P50和P75表示在某一時間內緩存請求所佔的比例,例如P50告訴咱們在47小時的時候有50%的請求是有緩存的,一樣,p75意味着75%的請求將是有緩存的。
移動端的測試數據告訴咱們大概在12小時的時候有50%的請求是有緩存的。
整體來看咱們的統計跟2007年是比較類似的,若是咱們firefox瀏覽器(32和更高版本)不計入統計的話:此次有緩存的比例最高點是84.1%,高於2007年的80%。
另外一方面,緩存的存在時間並非太長。基於咱們的研究,雖然在一個新版本發佈的47小時以後有42%的請求將會帶有緩存,可是這個緩存資源在電腦上存在時間也大概是這個時間。這個新的發現,對其餘網站頗有參考意義。
爲何緩存存在的時間不是太長?其實很是容易理解,從互聯網的發展來講,網站的體積從2007到如今發生了不小的變化。拿2007年年來講,那時候咱們家裏的網速大概是2.5M,Yahoo的首頁有168.1KB。如今個人手機都有了8G下行,Yahoo首頁已經變到768KB。如今市面上網頁的平均大小已經超過1MB了,這將給咱們的瀏覽器的良好運做帶來很大的壓力(譯者注:由於須要緩存的資源太多,超過瀏覽器設置的默認資源緩存大小會自動刪掉早期的一些緩存文件,例如ie默認的是50MB,而chrome的是320MB)。
所以合理利用瀏覽器緩存比8年以前更加有意義。
最佳實踐告訴咱們:儘可能用外鏈樣式表和JS、讓headers設置Cache-Control and ETag,並儘量的壓縮咱們的數據、用不一樣的網址管理緩存、分割須要頻繁更新的資源。這些優化方法不只適用於像facebook這樣規模的項目,其餘網站也能夠應用它們。雖然咱們的更新頻率會對緩存的優化帶來負面的影響,可是這個不是本次文章所研究的重點。事實上,咱們已經開始運用此次的研究成果來讓全部訪問facebook的用戶收益。
Chromium cache metrics
原文:https://code.facebook.com/posts/964122680272229/web-performance-cache-efficiency-exercise/
翻譯:TGideas - Allan