在8年之前,Yahoo團隊曾經對網頁中的快取做了比較詳盡的研究,但是隨著網際網路的高速發展,研究資料發生了一些變化。這篇文章主要是Facebook的web團隊對現在快取情況一些資料收集和研究。包括PC和移動端資源被快取的時間以及資源在存在的時間。網頁快取是效能優化很重要的因素,值得一讀。
能力有限,如有翻譯錯誤的地方,歡迎隨時找我交流,我會及時更正:)
正文:網頁載入速度是每個網站都應該重視的因素。但是往往被大家忽略。快取是一個提升網站訪問速度非常重要的因素(因為使用者在下次訪問的時候不需要重新計算或者下載已經快取的資源)
我們團隊(facebook web團隊)最近針對目前facebook.com沒有快取的現狀進行了一番討論,主要問題是:在facebook,.我們每天都會發布兩個版本,怎麼樣才能令快取更有效率?怎麼樣的快取策略才適合我們?
在找解決方案的時候, 我們發現雅虎效能優化研究部落格上已經有了一篇關於效能研究的文章。
但是令我們非常吃驚的是:20%的頁面訪問是在空快取的情況下進行的。但是這個研究結果距離現在有8年了,那個時代剛釋出IE7,jquery也剛釋出第一個版本,所以我們決定重新研究一下,看現在是不是有所改善。
重新研究:在之前的研究當中,Yahoo在伺服器建立了HTTP頭設定了圖片的過期時間和上次修改時間,如果圖片沒有發生改變,就用GET請求傳送給伺服器一個最後修改時間的資訊,如果圖片沒有修改,就返回304(沒有修改)來替換200(請求成功)。因為伺服器可以記錄瀏覽器請求的請求狀態,所以Yahoo用伺服器日誌來統計快取的使用者數。
像那樣的研究方法一樣,我們建立了一個既能傳送圖片請求也能在資料庫當中記錄日誌的PHP終點。這張圖片用http頭資訊來控制瀏覽器的快取和其他通過代理產生的快取。之後在使用者請求圖片的時候記錄這些資訊。
這個圖片HTTP頭資訊的設定是這樣的:
[img=Facebook,網頁,快取]http://ossweb-img.qq.com/upload/webplat/info/tgideas/201507/1438227497_1436653066_28235_imageAddr.jpg[/img]
但是因為一些已知的BUG,我們在IE7和IE8中把兩個屬性替換成了下面這樣:
[img=Facebook,網頁,快取]http://ossweb-img.qq.com/upload/webplat/info/tgideas/201507/1438227512_1436653066_28766_imageAddr.jpg[/img]
當瀏覽器傳送請求給圖片時候,將會發生兩件事情:
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端的瀏覽器分開來統計可能更加清楚:
[img=Facebook,網頁,快取]http://ossweb-img.qq.com/upload/webplat/info/tgideas/201507/1438227526_1436653066_28926_imageAddr.jpg[/img]
根據上面一週的資料來看:使用者用chrome和opera快取的機率更大。你可能注意到你這個圖表中並沒有firefox瀏覽器的資料,那是因為firefox 31版本以及更早期的版本在我們的統計中有80%的快取概率,但是在32版本和更高的版本當中有很明顯的下降。那是因為firefox的快取策略和我們的統計方法有點衝突(http://www.janbambas.cz/new-firefox-http-cache-enabled/),
所以我們就乾脆去掉了firefox瀏覽器的資料統計。
好了,現在讓我們來看看移動端的資料:
[img=Facebook,網頁,快取]http://ossweb-img.qq.com/upload/webplat/info/tgideas/201507/1438227540_1436653066_29425_imageAddr.jpg[/img]
可以看到,大部分瀏覽器的快取比例是在68%和84%之間。移動平臺的資料差別還是挺大的,我們想可能都是比較低端的移動裝置(https://code.facebook.com/posts/307478339448736/year-class-a-classification-system-for-android/)。除此以外資料跟桌面端還是比較相似的。
下面這個圖分別是移動端和手機端空快取使用者所佔的比例:
[img=Facebook,網頁,快取]http://ossweb-img.qq.com/upload/webplat/info/tgideas/201507/1438227552_1436653066_30265_imageAddr.jpg[/img]
平均來看,有44.6%的使用者是空快取的,這個也很符合Yahoo團隊在2007年做的研究。
更進一步:到這裡,文章還沒有完結。在Facebook,我們迭代速度非常快,每天幾乎都會發布兩個版本。這個驅動我們去思考,多長時間的快取設定適合我們呢?我們將if-modified-since這個檔案頭返回的時間減去當前時間來尋找答案。
所以我們根據上面的方法,我們統計了從第一次正常請求到發生304請求的時間(這說明了使用者從沒有快取到有快取經歷了多長時間),下面是資料生成的圖示: