The Will Will Web

記載著 Will 在網路世界的學習心得與技術分享

如何在 IIS 中將靜態檔案設定用戶端快取 (Client-side Cache)

當網站上線後,由於網站中許多靜態的網頁、圖檔、CSS、JavaScript 等資料都不會頻繁的變動,為了讓網頁的載入速度加快,我們通常都會將靜態檔案先設定 用戶端快取 (Client-side Cache),也就是所謂的 Expires Header 或稱 Cache Headers,這有別於我們在開發程式時所用的 伺服器端快取 (Server-side Cache)。

在尚未做出任何調整的情況下,Browser 與 Web Server 之間是用以下機制幫你加快網頁載入速度的:

1. 當瀏覽器第一次載入圖檔或其他靜態檔案時,IIS 會回傳 ETag 與 Last-Modified 這兩個 HTTP Header

HTTP Headers

2. 當瀏覽器第二次載入圖檔或其他靜態檔案時,瀏覽器就會傳送兩個特殊的 HTTP Header 給 IIS 伺服器,分別是 If-Modified-Since (如果檔案修改時間大於這個時間) 與 If-None-Match (如果伺服器的 ETag 不等於),然後伺服器會根據瀏覽器送來的 HTTP Header ���伺服器上的靜態檔案進行比對,若是條件符合的話,就代表伺服器上的檔案與本機的快取的版本不一樣,這時就會重新以 HTTP 200 回應新檔案。不過通常的狀況是檔案沒有做出任何變動,這時伺服器就會回應 HTTP 304 Not Modified 狀態,告知瀏覽器我不會回應檔案內容,僅有 HTTP Response Header 部分而已。

HTTP Headers

---

因為 Browser 不用下載檔案內容 (圖檔, CSS, JavaScript, ...),因此網頁下載的速度提升了,不過這不是最好的結果,因為網頁每次要下載圖片時,都還是會發出 HTTP Request 並等待 HTTP Response 回應,如果我們利用規劃完善的 用戶端快取 (Client-side Cache) 機制設定,那麼連 Browser 連 HTTP Request 都不會送出,而直接取用用戶端本機的快取檔案,這樣的頁面顯示速度最快!

如果要在 IIS6 中設定某一個目錄的用戶端快取 (Client-side Cache) 機制設定,最簡單的作法就是設定 HTTP 標頭 頁籤的「啟用內容的到期限制」,如下圖示:

設定 HTTP 標頭 頁籤的「啟用內容的到期限制」

如果你有多個目錄要執行快取的話,必須每個目錄都進行這類設定,例如:css, js, Content, .. 等目錄。

如果在 IIS7 下,那就更容易了,只要修改網站根目錄下的 web.config 檔,你可以找到 <system.webServer> 區段,並加入以下設定:

<staticContent>
    <clientCache cacheControlMaxAge="00:10:00" cacheControlMode="UseMaxAge"/>
</staticContent>

其中 cacheControlMaxAge 為 timeSpan,其格式為 d.hh:mm:ss,其中 d 是「天數」、hh 是小時、mm 是分鐘及 ss 是秒數,其中的天數是可省略的。這項設定沒有 GUI 介面可以協助你,必須手動設定。

---

設定好之後,請清除所有瀏覽器快取,然後再測試看取得的 HTTP Response Header 有什麼變化:

HTTP Headers

快取之後,你在點選其他頁面時,這些被快取的靜態檔案都不會再次下載,你將會發現網頁顯示速度飛快,如果兩張網頁內容差不多的話,甚至會感覺不到瀏覽器有換頁的感覺。

---

使用 用戶端快取 是有個致命的缺點,也就是當檔案已被下載快取後,若你的檔案在伺服器端被更新過,這時瀏覽器是完全不會收到更新通知的,要解決這個問題可以參考我另一篇文章:簡易克服CSS 被瀏覽器快取(Cache)的問題

相關連結