網站優化:瀏覽器緩存控制簡介及配置策略

說在開頭 javascript

《高性能建站指南》看了不少遍,一直沒有搞清楚緩存這一塊。。什麼expired,last-modified,eTag等等,本身只是知道,並無深刻了解,在http請求中,這些字段是如何判斷是否須要從服務端從新拿文件仍是利用緩存。看到了一篇不錯的文章,分享一下。 css



正文  html

   每次訪問網頁,一般瀏覽器會從服務器下載所需的資源,例如 HTML 文檔、圖片、CSS、JavaScript,甚至包括字體文件等。這裏面的許多文件(例如圖片)都是不多變更的,若是每次都要從服務器從新下載,會沒必要要地增長網頁載入時間,同時也會對服務器形成必定壓力。經過合理配置緩存策略,可令瀏覽器以某種方式把這些靜態的文件緩存起來,下次請求同一資源時,直接使用本地存儲的副本,而不是從服務器從新下載。
java


啓用緩存至少有兩點顯而易見的好處:web


減小頁面加載時間正則表達式

減小服務器負載apache


瀏覽器是否使用緩存、緩存多久,是由服務器控制的。準確來講,當瀏覽器請求一個網頁(或者其餘資源)時,服務器發回的響應的「響應頭」部分的某些字段指明瞭有關緩存的關鍵信息。瀏覽器


Cache-Control緩存


Cache-ControlHTTP 響應頭是 HTTP 1.1 協議新增的指令,每一個資源均可以經過設定 Cache-Control 來創建緩存策略。一般,可爲它指定一個max-age,表示緩存的最長時間,單位爲秒。例如,若設定Cache-Control: max-age=604800,則表示這個資源的有效時間爲 7 天。瀏覽器第一次獲取這個資源後,7 天以內若再次請求,一般都不會與服務器進行任何通訊,而是直接使用本地副本。安全


此外,還能夠爲 Cache-Control 指定public或private標記。若是使用 private,則表示該資源僅僅屬於發出請求的最終用戶,這將禁止中間服務器(如代理服務器)緩存此類資源。對於包含用戶我的信息的文件(如一個包含用戶名的 HTML 文檔),能夠設置 private,一方面因爲這些緩存對其餘用戶來講沒有任何意義,另外一方面用戶可能不但願相關文件儲存在不受信任的服務器上。須要指出的是,private 並不會使得緩存更加安全,它一樣會傳給中間服務器(若是網站對於傳輸的安全性要求很高,應該使用傳輸層安全措施)。對於 public,則容許全部服務器緩存該資源。一般狀況下,對於全部人均可以訪問的資源(例如網站的 logo、圖片、腳本等),Cache-Control 設爲 public 是合理的。


Expires


一樣是用來控制緩存,Expires響應頭從另外一個角度——指明緩存的具體過時日期,來控制資源什麼時候過時。在過時時間之內,若再次發起請求,一般瀏覽器都不會與服務器進行任何通訊,而是直接使用本地副本。Apache 服務器容許以多種方式,例如基於該資源的訪問時間或上次修改時間來設定 Expires 的值。注意,這裏的時間一概使用格林威治時間(Greenwich Mean Time, GMT),而非本地時間。


當 Expires 和 Cache-Control 同時出現時,一般後者會覆蓋前者的設定。因爲 Expires 對用戶的系統時間有所依賴,所以一般認爲使用 Cache-Control 是更好的選擇(基本上全部的瀏覽器都支持 Cache-Control 指令)。


Last-Modified 和 ETag


服務器可在 HTTP 返回頭中包含Last-Modified字段或者ETag字段。Last-Modified 表示被請求資源在服務器端的上次修改時間,而 ETag 則是一個惟一文件標識符,每次文件修改後都會生成一個新的 ETag。服務器經過向瀏覽器發送這兩個字段,來告知瀏覽器其得到的資源的版本。


不管經過 Cache-Control 仍是 Expires 設置緩存,在過時時間之內,當用戶點擊瀏覽器刷新按鈕時,爲了確保用戶所加載的資源是最新的,大部分瀏覽器不會再直接使用緩存中的數據,而是發出一個條件請求(Conditional GET Request)。對於這類請求,瀏覽器會在請求頭中包含If-Modified-Since或If-None-Match字段。前者即瀏覽器當初獲得的 Last-Modified;後者即瀏覽器當初獲得的 ETag。當服務器發現資源的更新時間晚於 If-Modified-Since 所提供的時間,或者資源在服務器端當前的 ETag 和 If-None-Match 提供的不符時,會響應整個資源,不然只會響應一個 304 Not Modified 狀態碼(所以瀏覽器將不須要從新下載整個資源)。這種機制能夠最大程度上減小數據下載量。此外,若是緩存的資源已過時,瀏覽器一般有兩種選擇:從新下載這個資源,或發出一個條件請求。不少瀏覽器都會採起後者,以節約資源。


因爲 Last-Modified 和 ETag 的做用是相同的(均爲向服務器驗證資源是否最新),所以只使用一個便可。一般認爲 Last-Modified 更好(它和 Expires 不一樣,由服務器生成,不依賴瀏覽器端時間)。


個人網站啓用緩存了嗎?


用瀏覽器的開發者工具或插件查看


爲了肯定是否啓用了緩存,只須要檢查服務器發回的「響應頭」就能夠。許多瀏覽器以及工具均可以檢查這些信息,咱們以 Firefox 的插件 Firebug 爲例。如圖所示:


wKioL1Z3aWLQ42LkAAA2YfwxRcE409.png

wKioL1Z3aWKyOhBjAAAjLcNDLXs412.png


沒有包含Cache-Control以及Expires信息。


在線檢測


也有一些方便的在線檢測服務,用於對網站速度給出建議,其中就會檢測緩存設置狀況。好比 Yahoo! 公司的 YSlow,以及百度站長工具等,都有相應的功能。你們能夠去百度那裏檢測一下,目前是不須要登陸便可檢測的。




使用緩存的策略


爲靜態資源設置長緩存時間


有些資源是很長時間不會改變的,好比網站的 logo 圖片、jQuery 庫、字體等,所以能夠爲它們設定「永不過時」的緩存時間,例如設定爲 10 年。


確保文件修改生效


有些時候咱們會修改一些資源,好比更新了 jQuery 版本,或網站的 CSS 樣式。若是這些資源已經被緩存,那麼除非用戶手工刷新頁面,不然要等緩存天然過時以後用戶纔會得到新版本。如何在這種狀況下強制瀏覽器從新下載呢?最有效的一個辦法就是在這類資源的文件名中包含版本信息,並在更改以後對應地修改文件名。瀏覽器發現文件更換後,天然沒法使用緩存,而會從新下載。


對於 HTML 文檔謹慎設定過時時間


大部分狀況下,對於其餘圖片、CSS、JavaScript 等資源的請求都來自一個單一的 HTML 文檔。對於這類頁面一般應該設定比較短的過時時間,或者乾脆不設定。由於若是這類頁面被緩存,那麼頁面中包含的資源的文件名等等信息都會一併被緩存,致使對它的更新難以確保當即對用戶生效。


引用靜態資源時,不要使用 Query String


Query String 就是例如?key=val的字符串,如

<script src="/static/js/func.js?v=a87ff8"></script>

這會阻止一部分較老的瀏覽器(包括 IE6 )對該資源進行緩存。


設定緩存的方法


對於 Apache 服務器,能夠經過 mod_expires 模塊來設定ExpiresHTTP 頭或Cache-ControlHTTP 頭的max-age指令。編輯相應目錄下的 .htaccess 文件,或直接對 Apache 的配置文件(根據服務器系統版本不一樣,可能爲httpd.conf或apache2.conf等)做出修改。


分文件類別設定


使用ExpiresByType能夠按照文件的 MIME Type 設定某一類文件的過時日期。例如:

<IfModule mod_expires.c>
    ExpiresActive On
    ExpiresByType text/css                "access plus 1 week"
    ExpiresByType application/javascript  "access plus 2 weeks"
    ExpiresByType p_w_picpath/x-icon            "access plus 6 months"
    ExpiresByType p_w_picpath/gif               "access plus 6 months"
    ExpiresByType p_w_picpath/png               "access plus 6 months"
    ExpiresByType p_w_picpath/jpeg              "access plus 6 months"
    ExpiresByType video/x-flv             "access plus 6 months"
    ExpiresByType application/pdf         "access plus 6 months"
</IfModule>

其中access plus 1 week表示將緩存過時設置爲訪問時間(即當前時間)以後的一週。若是將access替換爲modification,則緩存過時會被設定爲文件修改時間以後的一週。可使用的時間單位包括:

    years
    months
    weeks
    days
    hours
    minutes
    seconds

不一樣的時間也能夠進行組合,例如:

ExpiresByType text/html "access plus 1 month 15 days 2 hours"
ExpiresByType p_w_picpath/gif "modification plus 5 hours 3 minutes"

根據文件擴展名進行設置


若是但願根據擴展名來指定緩存規則,可使用FilesMatch配合正則表達式。爲了簡潔,我這裏只規定了ExpiresDefault。它的優先級很低,只會在對應文件沒有任何其餘規則可以匹配(包括上層目錄下的緩存規則)時生效。

<IfModule mod_expires.c>
    <FilesMatch "\.(css|js)$">
        ExpiresActive on 
        ExpiresDefault "access plus 1 week"
    </FilesMatch>
</IfModule>

對某些文件設定


同理,也能夠對某些文件啓用特定的緩存策略。注意,文件名中的點(.)是須要轉義的。

<IfModule mod_expires.c>
    <FilesMatch "^(example\.css|example\.js)$">
        ExpiresActive on 
        ExpiresDefault "access plus 1 week"
    </FilesMatch>
</IfModule>

對某一文件夾下的全部文件設定


對於靜態文件,一個比較方便的作法是將它們所有放到一個目錄下,並對該目錄下的全部文件設定。可是,此處須要注意防止其餘規則將ExpiresDefault覆蓋掉。

<IfModule mod_expires.c>
    ExpiresActive On
    ExpiresDefault "access plus 10 years"
</IfModule>


有用的工具及參考資料


Cache-Control header checker(可檢測給定的地址是否啓用了 Cache-Control,還會教你如何設定)

Caching Tutorial for Web Authors and Webmasters

HTTP 緩存 - Web Fundamentals(來自 Google Developers)

百度站長工具-頁面優化建議

h5bp/server-configs(HTML5 Boilerplate 提供了全部最流行的服務器的配置文件樣例)

相關文章
相關標籤/搜索