優化網站設計(三):對資源添加緩存控制

前言

網站設計的優化是一個很大的話題,有一些通用的原則,也有針對不一樣開發平臺的一些建議。這方面的研究一直沒有中止過,我在不一樣的場合也分享過這樣的話題。html

做爲通用的原則,雅虎的工程師團隊曾經給出過35個最佳實踐。這個列表請參考web

Best Practices for Speeding Up Your Web Site  http://developer.yahoo.com/performance/rules.html

同時,他們還發布了一個相應的測試工具Yslow http://developer.yahoo.com/yslow/chrome

我強烈推薦全部的網站開發人員都應該學習這些最佳實踐,並結合本身的實際項目狀況進行應用。api

接下來的一段時間,我將結合ASP.NET這個開發平臺,針對這些原則,經過一個系列文章的形式,作些講解和演繹,以幫助你們更好地理解這些原則,而且更好地使用他們。瀏覽器

準備工做

爲了跟隨我進行後續的學習,你須要準備以下的開發環境和工具緩存

  1. Google Chrome 或者firefox ,而且安裝 Yslow這個擴展組件.請注意,這個組件是雅虎提供的,但目前沒有針對IE的版本。
    1. https://chrome.google.com/webstore/detail/yslow/ninejjcohidippngpapiilnmkgllmakh
    2. https://addons.mozilla.org/en-US/firefox/addon/yslow/
    3. 你應該對這些瀏覽器的開發人員工具備所瞭解,你能夠經過按下F12鍵調出這個工具。
  2. Visaul Studio 2010 SP1 或更高版本,推薦使用Visual Studio 2012
    1. http://www.microsoft.com/visualstudio/eng/downloads
  3. 你須要對ASP.NET的開發基本流程和核心技術有至關的瞭解,本系列文章很難對基礎知識作普及。

本文要討論的話題

緩存!這是一條多麼重要的原則。幾乎全部的網站優化的書籍或者文章中都會提到這個原則,並且目前在運行的一些網站都或多或少地使用到了這個技術。這個原則的相關概念能夠參考這裏:http://developer.yahoo.com/performance/rules.html#expires 服務器

咱們仍是以博客園的主頁爲例,經過簡單的監控就能發現,他們大量地使用了緩存的功能(針對不一樣資源,緩存的策略可能略有不一樣,請注意觀察max-age的值,以秒爲單位,有興趣的同窗能夠計算一下)工具

image

 

接下來,我會從幾個方面,和你們來談談緩存的問題性能

1.緩存的概念

緩存是服務器與客戶端(或者中間的代理服務器)之間的一種約定,利用緩存能夠明顯地減小重複從服務器下載內容的次數,這樣就能夠極大地提升吞吐量以及響應速度。在HTTP 1.1協議中,對於緩存有明確的,詳細的說明:http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html學習

因爲緩存如此重要,因此對於不少瀏覽器而言(尤爲是現代瀏覽器),他們默認就會嘗試對靜態內容進行緩存。(這裏先賣一個關子,你們以爲默認狀況下它會緩存多長時間呢?)

下圖能夠很好地揭示緩存的做用

image

這是我兩次訪問一個簡單的頁面的情形,第一次(我用顏色選中的8個請求)的時候,由於沒有緩存,因此全部的內容資源(動態的和靜態的)都須要下載。瀏覽器會根據狀況對其進行緩存(一般就是對於靜態內容它會有一個緩存的策略,後面再細述)。可是第二次訪問,就徹底不同了,只有第1個請求是須要下載內容的(這是一個動態頁面),其餘的7個內容都是無需下載的(你能夠看到狀態碼是304,並且Body都是0)

 

2.靜態資源的緩存及其設置

默認狀況下,瀏覽器(至少絕大多數現代瀏覽器)都會對網站中的靜態內容進行緩存。常見的靜態內容包括

  1. HTM,HTML文件
  2. JAVASCRIPT文件
  3. CSS文件
  4. 圖片文件

若是服務器端不作任何的設置,那麼默認狀況下它緩存多長時間呢?答案是:可能好久,這個取決於兩個因素

  1. 瀏覽器緩存中的這個文件是否被清理(多是用戶手工地進行清理,有的公司也可能會設置統一的策略自動在瀏覽器關閉的時候清理)
  2. 服務器對應的文件是否有更新

這裏就要講到那個304的狀態碼了. 這個狀態碼的意思是:Not Modified(未更改)。爲何會產生這樣的狀態碼呢?其實能夠經過下面三個截圖來理解清楚

第一次請求某靜態資源的時候,服務器會在返回內容(狀態碼爲200)的同時,包含一個特殊的Header,叫作Last-Modified ,這個Header會記錄在服務器端該文件最後修改的時間。以下圖所示

image

而後,瀏覽器會將此文件緩存起來。

接下來若是須要第二次訪問這個文件,瀏覽器發起的請求中,也會包含一個特殊的Header

image
這個Header的意思是說,要檢查從這個時間後是否有修改。若是該文件沒有修改過,則服務器就會返回304這個狀態碼,而且不會返回任何內容。

image

瀏覽器收到了304這個狀態碼的話,就會使用本身已經緩存的那個版本進行呈現。

咱們固然也能夠靜態資源的緩存策略進行人工的干預,這個能夠經過兩個途徑來實現

  1. 經過IIS 管理界面。選擇某個站點,而後在右側的功能面板中,選擇「Http Response Header」,以下圖所示

image

而後在功能頁面中,點擊右側的「Set Common Header…」 這個Action

image

而後在彈出的對話框中設置Expire Web Content的選項

image

這裏默認會有三個策略:當即過時,在一個相對時間範圍內過時,在一個絕對時間後過時。你能夠根據本身的需求進行設置。

【備註】這些設置僅僅影響靜態資源。

  1. 直接修改web.config文件

上面提到的經過IIS管理界面對靜態資源配置到期時間(其實也就是指一個緩存的時間),這個作法適合給管理員使用。做爲開發人員,若是你但願本身來控制這些選項,那麼能夠直接在網站的配置文件(web.config)中添加相關的配置便可。

 <system.webServer>
        <staticContent>
            <clientCache cacheControlMode="UseMaxAge" cacheControlMaxAge="1.00:00:00" />
        </staticContent>
    </system.webServer>

 

須要注意的是,在以前的截圖中,有些特殊的腳本,它們的緩存時間是不受這個配置影響的。

image

他們是默認緩存一年的.這些特殊的腳本(或者樣式表)實際上是多個文件的組合,若是對這一點不太瞭解,請參考我以前的一篇文章

優化網站設計(一):減小請求數

3.動態資源的緩存及其設置

咱們上面討論到了靜態資源的緩存及其設置,可是對於如今的大部分網站來講,光有靜態資源是遠遠不夠的,咱們會有不少動態資源,典型的就是動態頁面(例如aspx頁面),那麼對於這種動態資源,是否也有可能進行必定的緩存呢?

答案是確定的,但對於動態資源的緩存細節至關多,恐怕要超出本文的範疇。我強烈推薦你們詳細閱讀MSDN中的這篇文檔 :

http://msdn.microsoft.com/en-us/library/aa478965.aspx (ASP.NET Caching: Techniques and Best Practices)

 

我這裏爲你們總結一下對動態資源進行緩存的幾種作法

  1. 頁面緩存,在頁面中使用OutputCache,適合於對整個頁面全部內容作緩存
  2. 片斷緩存,在用戶控件中使用OutputCache,適合於對頁面的一部分(一般封裝爲一個用戶控件)內容作緩存
    • 在MVC中,一樣能夠在Action上面使用OutputCache這個Attribute來定義緩存設置
  3. 數據緩存,在代碼中訪問Cache對象,適合對多個頁面中可能會用到的共享數據作精細的緩存控制

值得注意的是,這三種作法並不是是互斥的,在實際的應用中,他們會相互結合起來使用。

 

另外,除了給頁面或者控件設置OutputCache(爲了靈活起見,建議結合CacheProfile)以外,若是確實某些緩存的設置須要動態決定,也能夠採用以下的方式來實現一樣的效果

Response.Cache.SetExpires(DateTime.Now.AddSeconds(60));
Response.Cache.SetCacheability(HttpCacheability.Public);
Response.Cache.SetValidUntilExpires(false);
Response.Cache.VaryByParams["Category"] = true;

if (Response.Cache.VaryByParams["Category"])
{
   //...
}

關於Response.Cache的全部屬性和操做,有興趣的能夠參考 http://msdn.microsoft.com/EN-US/library/system.web.httpcachepolicy.aspx

【備註】本文以前提到的Bundle默認設置爲1年的過時時間就是經過這種方式來實現的。

 

 

4.緩存的反面

緩存是一種頗有用的技術,幾乎全部人都知道它的好處。如今的開發平臺都比較強大,讓咱們能夠有比較簡單的方式來實現緩存。

可是,緩存有它的一些代價,或者說有反面的一些問題須要考慮。典型的問題在於

  1.  版本控制
  2. 容量問題
    • 靜態資源一般是緩存在客戶端的(除非服務器端作特殊設置,IIS 7開始支持在服務器端——甚至內核模式——中緩存內容),他們一般對服務器影響不大。
    • 但動態資源的緩存,一般是緩存在服務器端的(或者客戶端和服務器端各有一份),因此須要佔用服務器的內存空間。
    • 若是不加以限制(或者不作周全的考慮),則極可能會由於緩存了過多的內容,而致使服務器的內存出現爭用的問題。
      • 這裏留一個問題,請問ASP.NET應用程序的緩存功能,默認最多可使用多少服務器內存?
    • 這裏所謂的周全考慮,是指咱們須要對緩存的必要性進行評估。應該只緩存那些確實有必要緩存的內容。這個說來容易,實際上作起來倒是不那麼容易的。
相關文章
相關標籤/搜索