客戶(hù)端圖片緩存 收藏
原文地址:Caching Images in ASP.NET , 版權歸原文作者所有。
引言:
在一個(gè)Web應用程序中,可以通過(guò)很多種方法來(lái)改善其性能,其中最簡(jiǎn)單但也是最有效的方法就是在客戶(hù)端緩存圖片,這篇文章就是告訴你如何在你的站點(diǎn)中實(shí)現圖片的緩存。
問(wèn)題:
我曾經(jīng)建立過(guò)一個(gè)站點(diǎn),在CSS樣式表中使用了很多圖片來(lái)作為菜單項的背景。網(wǎng)站完成之后,我使用Microsoft Network Monitor(微軟的一款流量分析工具,可從微軟下載中心下載)對網(wǎng)站的流量進(jìn)行了統計,發(fā)現每次對首頁(yè)的訪(fǎng)問(wèn)都會(huì )對20個(gè)不同的文件發(fā)出請求,其中一半以上都來(lái)至于對菜單背景圖片的請求。
有兩種方法可以解決這個(gè)問(wèn)題,第一種方法是通過(guò)IIS實(shí)現圖片的緩存;第二種方法是直接在A(yíng)SP.NET實(shí)現緩存。
通過(guò)IIS緩存圖片:
這種方法非常簡(jiǎn)單,首先選中IIS管理器中選中一個(gè)文件或文件夾,右鍵單擊,打開(kāi)屬性對話(huà)框。
選中HTTP頭選項卡中的“啟用內容過(guò)期”,并根據需要設定過(guò)期時(shí)間。這樣客戶(hù)端就會(huì )對你設定的文件進(jìn)行緩存,直到緩存過(guò)期才會(huì )向服務(wù)端發(fā)起新的請求。
當你對IIS擁有足夠的管理權限,并且網(wǎng)站的圖片位置相對比較集中時(shí),這種方法是一種很好的選擇。但這樣的條件往往得不到滿(mǎn)足,這個(gè)時(shí)候你就需要使用第二種方法了。
通過(guò)HttpHandle緩存圖片
為了獲取對ASP.NET的請求,需要編寫(xiě)一個(gè)自定義HttpHandle來(lái)對圖片文件(*.jpg;*.gif;*.png)進(jìn)行監聽(tīng)。首先在Visuan Studio中新建一個(gè)類(lèi)庫工程,取名為CachingHandler,負責處理對圖片的請求。CachingHandler需要實(shí)現IHttpHandle接口,在IHttpHandle接口中,IsReusable屬性指示其他請求是否可以使用該IHttpHandler實(shí)例,ProcessRequest()方法負責獲取和發(fā)送數據。
配置Web.Config文件
在上面的代碼中,我們使用了一個(gè)自定義類(lèi)ConfigurationSection來(lái)讀寫(xiě)Web.Config的信息,下面是這個(gè)類(lèi)的實(shí)現。
ConfigurationSection類(lèi):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>
在站點(diǎn)中完成以上代碼的添加之后,再次使用Microsoft Network Monitor進(jìn)行測試,第一次訪(fǎng)問(wèn)首頁(yè)時(shí)依然是20個(gè)不同的請求,但到了第二次訪(fǎng)問(wèn)請求就變?yōu)榱?個(gè),因為所有的圖片文件都已經(jīng)緩存到了客戶(hù)端。
在原文中,作者還提供了一個(gè)完整的Solution來(lái)測試圖片緩存功能,大家可以自由下載.