網頁制作POLUOLUO文章簡介:從http協議和浏覽器的工作機制的角度講,總會有一些不確定因素在影響緩存的實際發生,比如如果浏覽器設置所有文件都不緩存,服務器端的任何緩存優化都不起作用,所以應當使用多手段配合完成合理的緩存設計,使得網站既可以隨時更新又能保證飽和的緩存,以保證良好的用戶
web頁面緩存影響http請求數和請求文件大小,是影響前端體驗最重要的因素。在項目開發中,總會有一些js或者css文件是頻繁修改的,比如yahoo的jake中的js標簽引用的文件,也總會有一些js或css是永遠不會修改的,比如yui的組件js文件,因此在做性能優化的時候這兩者應當區分開,即頻繁修改的文件減小緩存約束,相對固定不變的文件要強制緩存。
從http協議和浏覽器的工作機制的角度講,總會有一些不確定因素在影響緩存的實際發生,比如如果浏覽器設置所有文件都不緩存,服務器端的任何緩存優化都不起作用,所以應當使用多手段配合完成合理的緩存設計,使得網站既可以隨時更新又能保證飽和的緩存,以保證良好的用戶體驗。在yui的框架下,種子文件總會占用一個http請求,也就是說,浏覽器在解析script標簽的時候,去處理這個src所指向的js文件通常會帶有Cache-control: no-cache,或者Cache-Control: max-age=0,這種情況下服務器端返回的Cache-Control自然不會起作用。比如taobao首頁的tbra種子文件,無論如何都會帶一個cache-control的標簽,如圖:
因此這個種子總會占用一個http請求,而由yui動態加載的js文件和css文件則會被強制緩存,通過js發起的http請求是可以定義http的頭字段的,但往往需要cdn服務器的支持,比如cn.yimg.com、taobao的cdn和老美的yimg都強制將資源文件緩存10年。比如這個是老美的yimg過期時間,上圖的taobao cnd也是如此。
真正起作用的緩存則是在動態加載js的過程中,也就是說只有yui動態get一個javascript文件的時候才會在請求的時候加上Cache-Control字段,這樣的話浏覽器就會截獲這個請求,根據Cache-Control字段的參數去本地緩存中取文件,這樣就不會實際占用一個http請求,這對頁面的性能提高是有決定性作用的。這也是為什麼yui團隊始終如一的推薦使用loader動態加載模塊的原因。也正是因為這樣,用手寫script標簽的形式來取js文件是非常耗費性能的。比如這樣一個測試頁面,清空緩存後的所有12個js請求每個都是完整的200http請求:
當按f5刷新的時候就變為:
這樣實際請求數就降低為2個,這就是yui動態加載js文件的優勢,而在taobao首頁不論怎麼按f5刷新,請求數都不會減少。
如果請求數無法降低下來,則可以減小請求本身的大小,常用的是最後修改時間和Etag兩個字段,etag更加常用也更加准確一些,etag可以判斷文件是否被修改過,如果修改過則返回一個200的http回應,如果沒有則返回304,告訴浏覽器取緩存取文件。使用etag其實用最簡單的摘要算法就可以,比如md5,反正只是一個完整性判斷。雅虎的yimg服務器能更加精准的判斷文件是否修改,因此即便js文件的請求是通過手寫script標簽發起的,也會返回304,可以看到yahoo首頁f5刷新後,yimg域的js請求全都是304,有一半的內容是從緩存中取的:
而taobao的cdn就不那麼准確了,用f5刷了很多次taobao首頁,發現那個頑固的tbra.js始終是200,如圖:
這裡的cn.yimg.com的js乖乖的返回了304,而tbra始終是200,這會就造成貸款浪費,還好文件只有25k,對體驗影響不大,可能是taobao的cdn沒有對etag做優化,我看到的每次etag都是不一樣的,按理說文件不修改etag應該不變才對,是加了時間戳的原因嗎,還需要再研究研究。