客戶端圖片緩存 收藏
原文地址:Caching Images in ASP.NET , 版權(quán)歸原文作者所有。
引言:
在一個Web應(yīng)用程序中,可以通過很多種方法來改善其性能,其中最簡單但也是最有效的方法就是在客戶端緩存圖片,這篇文章就是告訴你如何在你的站點中實現(xiàn)圖片的緩存。
問題:
我曾經(jīng)建立過一個站點,在CSS樣式表中使用了很多圖片來作為菜單項的背景。網(wǎng)站完成之后,我使用Microsoft Network Monitor(微軟的一款流量分析工具,可從微軟下載中心下載)對網(wǎng)站的流量進行了統(tǒng)計,發(fā)現(xiàn)每次對首頁的訪問都會對20個不同的文件發(fā)出請求,其中一半以上都來至于對菜單背景圖片的請求。
有兩種方法可以解決這個問題,第一種方法是通過IIS實現(xiàn)圖片的緩存;第二種方法是直接在ASP.NET實現(xiàn)緩存。
通過IIS緩存圖片:
這種方法非常簡單,首先選中IIS管理器中選中一個文件或文件夾,右鍵單擊,打開屬性對話框。
選中HTTP頭選項卡中的“啟用內(nèi)容過期”,并根據(jù)需要設(shè)定過期時間。這樣客戶端就會對你設(shè)定的文件進行緩存,直到緩存過期才會向服務(wù)端發(fā)起新的請求。
當(dāng)你對IIS擁有足夠的管理權(quán)限,并且網(wǎng)站的圖片位置相對比較集中時,這種方法是一種很好的選擇。但這樣的條件往往得不到滿足,這個時候你就需要使用第二種方法了。
通過HttpHandle緩存圖片
為了獲取對ASP.NET的請求,需要編寫一個自定義HttpHandle來對圖片文件(*.jpg;*.gif;*.png)進行監(jiān)聽。首先在Visuan Studio中新建一個類庫工程,取名為CachingHandler,負責(zé)處理對圖片的請求。CachingHandler需要實現(xiàn)IHttpHandle接口,在IHttpHandle接口中,IsReusable屬性指示其他請求是否可以使用該IHttpHandler實例,ProcessRequest()方法負責(zé)獲取和發(fā)送數(shù)據(jù)。
配置Web.Config文件
在上面的代碼中,我們使用了一個自定義類ConfigurationSection來讀寫Web.Config的信息,下面是這個類的實現(xiàn)。
ConfigurationSection類:CachingSection.cs
最后是在Web.Config文件中添加相關(guān)的信息:
namespace SoftwareArchitects.Web
{
public class CachingHandler : IHttpHandler
{
public bool IsReusable
{
get { return true; }
}
public void ProcessRequest(HttpContext context)
{
string file = context.Server.MapPath
(context.Request.FilePath.Replace(".ashx", ""));
string filename = file.Substring(file.LastIndexOf('\\') + 1);
string extension = file.Substring(file.LastIndexOf('.') + 1);
CachingSection config = (CachingSection)context.GetSection
("SoftwareArchitects/Caching");
if (config != null)
{
context.Response.Cache.SetExpires
(DateTime.Now.Add(config.CachingTimeSpan));
context.Response.Cache.SetCacheability
(HttpCacheability.Public);
context.Response.Cache.SetValidUntilExpires(false);
FileExtension fileExtension = config.FileExtensions[extension];
if (fileExtension != null)
{
context.Response.ContentType = fileExtension.ContentType;
}
}
context.Response.AddHeader("content-disposition",
"inline; filename=" + filename);
context.Response.WriteFile(file);
}
}
}
namespace SoftwareArchitects.Web.Configuration
{
/// <summary>
/// Configuration for caching
/// </summary>
public class CachingSection : ConfigurationSection
{
[ConfigurationProperty("CachingTimeSpan", IsRequired = true)]
public TimeSpan CachingTimeSpan
{
get { return (TimeSpan)base["CachingTimeSpan"]; }
set { base["CachingTimeSpan"] = value; }
}
[ConfigurationProperty("FileExtensions", IsDefaultCollection = true,
IsRequired = true)]
public FileExtensionCollection FileExtensions
{
get { return ((FileExtensionCollection)base["FileExtensions"]); }
}
}
/// <summary>
/// List of available file extensions
/// </summary>
public class FileExtensionCollection : ConfigurationElementCollection
{
...
}
/// <summary>
/// Configuration for a file extension
/// </summary>
public class FileExtension : ConfigurationElement
{
[ConfigurationProperty("Extension", IsRequired = true)]
public string Extension
{
get { return (string)base["Extension"]; }
set { base["Extension"] = value.Replace(".", ""); }
}
[ConfigurationProperty("ContentType", IsRequired = true)]
public string ContentType
{
get { return (string)base["ContentType"]; }
set { base["ContentType"] = value; }
}
}
}
完整的
<configuration>
<configSections>
<sectionGroup name="SoftwareArchitects">
<section name="Caching" requirePermission="false"
type="SoftwareArchitects.Web.Configuration.CachingSection,
SoftwareArchitects.Web.CachingHandler" />
</sectionGroup>
</configSections>
<SoftwareArchitects>
<Caching CachingTimeSpan="1">
<FileExtensions>
<add Extension="gif" ContentType="image\gif" />
<add Extension="jpg" ContentType="image\jpeg" />
<add Extension="png" ContentType="image\png" />
</FileExtensions>
</Caching>
</SoftwareArchitects>
...
<httpHandlers>
<add verb="*" path="*.gif.ashx"
type="SoftwareArchitects.Web.CachingHandler,
SoftwareArchitects.Web.CachingHandler"/>
<add verb="*" path="*.jpg.ashx"
type="SoftwareArchitects.Web.CachingHandler,
SoftwareArchitects.Web.CachingHandler"/>
<add verb="*" path="*.png.ashx"
type="SoftwareArchitects.Web.CachingHandler,
SoftwareArchitects.Web.CachingHandler"/>
</httpHandlers>
</configuration>
在站點中完成以上代碼的添加之后,再次使用Microsoft Network Monitor進行測試,第一次訪問首頁時依然是20個不同的請求,但到了第二次訪問請求就變?yōu)榱?個,因為所有的圖片文件都已經(jīng)緩存到了客戶端。
在原文中,作者還提供了一個完整的Solution來測試圖片緩存功能,大家可以自由下載.