增加Expires Header Add an Expires Header【轉(zhuǎn)】
當前位置:點晴教程→知識管理交流
→『 技術文檔交流 』
原文地址: http://blog.csdn.net/FrankTaylor/archive/2008/12/30/3657335.aspx 在您設計網(wǎng)頁時,快速的響應時間不應該是你唯一要考慮的,如果僅僅是這樣,那我們采用法則1,把我們的頁面設計成一個極端的網(wǎng)頁:沒有任何圖片,script,樣式表。我們都明白,圖片、script、樣式表這些組件可以增強用戶體驗,雖然它們會給頁面帶來較長的載入時間。你幸運了,在這一章介紹的法則3,我就要向你介紹如何最大限度地利用瀏覽器的緩存來使這些頁面組件更高效的為我們的頁面服務。 現(xiàn)在的網(wǎng)頁所包含的組件越來越豐富,java applet去了,F(xiàn)lash來了,script也不可缺少,隨著div的大潮,css樣式表也少不了...... 所以用戶若第一次訪問您的網(wǎng)頁,則可能會產(chǎn)生多個HTTP請求;但如果您在請求返回中使用Expires頭信息,則可以緩存這些組件,避免在隨后的訪問中產(chǎn)生不必要的HTTP請求,Expires頭信息最常用于圖片,其實它適合應用在所有的組件中,如scripts,樣式表和Flash。但大多數(shù)當今的熱門網(wǎng)站目前并沒有這樣做。在這一章節(jié)中我會提及如何讓這些網(wǎng)站可以更快。在使用Header頭信息時,也可能會有一定的額外開銷,這點會在 "改變文件名"段落中再詳談. Expires Header 瀏覽器使用緩存來減少HTTP請求數(shù)和減少HTTP的響應數(shù)據(jù)量,以達到更快的加載頁面。web服務器通過Expries header來告訴web客戶端(John:主要是瀏覽器)當前返回的組件在我指定的時間以前都是可用的,你(瀏覽器)可以留著下次備用(John:有點像我們在超市買牛奶時,隨包裝袋上返回的過期日期)。Expries header 在HTTP規(guī)范中描述為 "the date/time after which the response is considered stale.",它附帶在HTTP的響應中返回給客戶端。 如上圖,這是一個典型的expries header ,它告訴瀏覽器,直到2010年4月15日這個請示的返回都不會變化。如果這個頭信息是隨著一個圖片返回的,那瀏覽器就會緩存這個圖片,以為其后的頁面瀏覽直接使用,以減少一個HTTP請示。 Max-Age and mod_expires 在我解釋緩存是如何更好的提升性能之前,有必要介紹一下與Expries header相關的幾個頭信息。Cache-Control header是在HTTP/1.1中被引入以彌補Expries header的不足。因為Expries header使用的是一個具體的日期,它就要求服務器與客戶端之間要有嚴格的時鐘檢查,并且當過期日期到來之后,服務器端還必須配置一個新日期。 相反,Cache-Control 使用max-age來指定一個時間段來標識一個組件能使用多長時間。這個max-age是以秒為單位來描述的(John:有點保質(zhì)期的概念)。如果在這個保質(zhì)期內(nèi),這個組件再被請求,瀏覽器就直接使用緩存里的就行了。下面就是一個返回10年保質(zhì)期的頭信息。 使用Cache-Control雖然彌補了Expires的不足,但我們?nèi)匀贿€是得使用 Expires header以兼容那些不支持HTTP/1.1的瀏覽器(盡管這些流量可能還不到1%)。所以我們一般同時使用Expires和Cache- Control max-age,按HTTP規(guī)范這時會以max-age的時間為優(yōu)先考慮,所以我們還是避免不了服務器與客戶端之間的時鐘檢查和服務器端的新日期配置。 幸運的是我們有Apache的 mod_expires模塊,能讓我們像設置max-age那樣來配置Expires header,它使用ExpiresDefault來設置一個時間段,如下,為圖片,scripts和樣式表設置10年的有效期: <FilesMatch "\.(gif|jpg|js|css)$"> ExpiresDefault "access plus 10 years" </FilesMatch> 這個時間可以是年,月,周,天,小時,分鐘甚至是秒。使用了這個模塊,所有的響應返回中就會同時帶著 Expires header 和 Cache-Control max-age 頭信息: 其中Expires header所攜帶的過期時間具體是多少,則依賴于每個客戶端什么時間發(fā)出的請求,在上面的例子中,始終是10年。這樣就避免了我們每次在到期后都要重新設置服務器,mod_expires會搞定一切。 圖3-1是對10大網(wǎng)站使用這些headr的一個調(diào)查。有7家使用了這些header,其中有5家同時使用了 Expires 和 Cache-Control max-age(John:推薦)。各有2家分別只使用 Expires 或Cache-Control max-age。很遺憾有3家什么也沒使用。 Empty Cache vs. Primed Cache 使用Expires header只會影響已經(jīng)訪問過的頁面和組件,當用戶第一次訪問您的頁面時無法避免的會有比較多的HTTP請求數(shù),因為這時瀏覽器的緩存里是空的。所以如果您的網(wǎng)站能吸引用戶訪問更多的頁面,并經(jīng)常在此停留,我們所做的緩存工作才有效果。 不僅僅是圖片 More Than Just Images 一般Expires header常用于圖片,其實這并不是最佳實踐。Expires header應該應用于所有那些不經(jīng)常變動的組件,script,樣式表或Flash組件。 在理想情況下,所有組件都在一個頁面內(nèi),并且都有一個未過期的Expries header,而隨后瀏覽的頁面只一個對HTML源文件的HTTP請求,其余的組件都在瀏覽器的緩存中直接提供,這時的響應時間會提高50%甚至更多。 我調(diào)查了美國的10大網(wǎng)站,并記錄了其中有多少圖片,script和樣式表是設置了至少30天有效期的Expires 或是 Cache-Control max-age header,如表3-2所示,情況并不是太好,圖中所列的是被緩存至少30天的組件數(shù),分母是該網(wǎng)站上的所有的該類型組件數(shù),分子是被加了過期 header的組件數(shù)。 • 有5家網(wǎng)站把大多數(shù)圖片的緩存有效期設為30天以上. • 有4家網(wǎng)站把大多數(shù)樣式表的緩存有效期設為30天以上. • 有2家網(wǎng)站把大多數(shù)script的緩存有效期設為30天以上. 從上圖的百分比中俺發(fā)現(xiàn)有74.7%的組件沒有被緩存或是有效期低于30天。一種解釋就是這些組件因為業(yè)務關系而不應該被緩存,如新聞網(wǎng)站 CNN.com就是個例子,138張圖片中沒有一張被緩存,這是因為很多新聞照片要被不斷更新而不必緩存在用戶端,所以這時更適合用Last- Modified heade,來通過組件的最后修改時間判斷是否要讀取新數(shù)據(jù)。 表3-2的最后一項,顯示了未被緩存的組件的最后修改時間的中分線,就CNN.com來說有一半的未緩存組件的最后修改時間是在227天前了,很顯然這些組件是應該被緩存的。 這種情況也曾發(fā)生在Yahoo!,在過去,Yahoo!并沒有緩存script,樣式表和一些圖片,是因為我們認為這樣是經(jīng)常變化的,用戶有必要每次訪問時都去請求一次以獲取最新的??蓡栴}是,在實際應用中,這些組件并不是我們想像中的那樣要經(jīng)常變化更新,我意識到應該把它們緩存來提升用戶體驗。后來,Yahoo!選擇了去緩存它們,哪怕會帶來一些額外的開發(fā)花銷,這就是我馬上要談到的Revving Filenames。 改變文件名 Revving Filenames 如果我們已經(jīng)為組件設置了緩存,可當這些組件又需要更新時,用戶如何才到得到最新的組件呢?由我們前面介紹的Expires 或是 Cache-Control max-age header 都會讓瀏覽器不檢查任何改變,直接從本地硬盤中讀取緩存,除非是過了有效期。所以我們能做的,就是在HTML頁面中改變這個組件的文件名。在Mark Nottingham的文章"Caching Tutorial for Web Authors and Webmasters"談到這個問題: 優(yōu)選的方案還是改變它們的鏈接;只有這樣,用戶才能從服務器上獲取更新。(The most effective solution is to change any links to them; that way, completely new representations will be loaded fresh from the origin server.) 說白了,還是要改變文件名。在已有的頁面中改變文件名可能是件頭疼的煩事,但是,不得不這樣,如果您使用的是PHP,Perl等動態(tài)的頁面,不妨利用一個變量為所有的組件命名,這樣換起文件名來比較省事。在Yahoo!,我們是在組件名后面跟上版本號(如,yahoo_2.0.6.js),把這個版本號做為一個變量寫在程序中,真的很省事。 舉例 Examples 下面的兩個鏈接,包包含有相同的組件:6個圖片,3個script和1個樣式表。第一個鏈接沒有任何Expires header,而第二個鏈接,全有。 No Expires http://stevesouders.com/hpws/expiresoff.php Far Future Expires http://stevesouders.com/hpws/expireson.php 我在900Kbps的DSL下測試,加了過期頭設置的鏈接頁面訪問時間會減少600~260毫秒,能提升57%,如果頁面的組件再多一點,這個百分比還會更高。 要說明一點,并不是說沒有加過期頭的組件就不會被瀏覽器緩存,它們也會被緩存,還記得我在Chapter B 中介紹的有條件的GET請求嗎,只不過,會多一個HTTP請求到服務器端以詢問這個組件是否有效,如果這個組件的最后修改時間和以前一下,則直接使用緩存中的版本,HTTP返回中將不帶這個組件的具體數(shù)據(jù)了。 為您頁面上的組件貼上保質(zhì)期吧,再加有有條件的GET請求,帶來的會是減少近一半的HTTP請求數(shù)還有不必要的數(shù)據(jù)傳輸。 該文章在 2010/12/15 0:08:15 編輯過 |
關鍵字查詢
相關文章
正在查詢... |