溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

ASP.NET組件System.Web.Optimization運行原理的示例分析

發(fā)布時間:2021-09-22 09:40:02 來源:億速云 閱讀:130 作者:小新 欄目:開發(fā)技術

這篇文章主要介紹了ASP.NET組件System.Web.Optimization運行原理的示例分析,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。

1】開篇介紹

將簡單的分析一下有關靜態(tài)文件捆綁的ASP.NET組件System.Web.Optimization的運行原理及基本的緩存問題:

在我們的項目里面充斥著很多靜態(tài)文件,為了追求模塊化、插件化很多靜態(tài)文件都被設計成模塊的方式或者被分解,在需要的時候在通過組合的方式在UI層上使用;這就帶來一個問題,文件多了會影響瀏覽器加載頁面的速度,而且由于瀏覽器的并發(fā)限制,對于并行的請求不是無限制的,所以捆綁靜態(tài)文件的功能就產(chǎn)生;其實在以前,IIS還沒有集成管道模型的時候我們只能通過動態(tài)資源的方式進行輸出,也就是我們經(jīng)常在*aspx頁面里看見很多*.axd結尾的請求,當然多數(shù)情況下是配合ASP.NETAJAX用來輸出動態(tài)JS、HTMDOM、CSS用的;

最新的IIS已經(jīng)很好的集成了ASP.NET管道模型,也就是說我們完全可以通過ASP.NET本身的擴展來控制所有經(jīng)過IIS的請求,包括靜態(tài)文件,所以讓捆綁靜態(tài)文件成為了可能;

下面我們將分析一下System.Web.Optimization組件的基本運行原理,它是如何動態(tài)加載的,如何控制緩存的;

2】System.Web.Optimization 組件

每當我們新建一個ASP.NETMVC4站點的時候都會在~/App_Start目錄下有一個BundleConfig.cs的啟動文件,當然創(chuàng)建其他的ASP.NET4.0及4.0以上的項目也會有;

我第一次看見這個文件實在讓我困惑,所以我打算簡單的分析一下,知道其基本原理;

ASP.NET組件System.Web.Optimization運行原理的示例分析

代碼是一個靜態(tài)方法,然后傳入一個BundleCollection集合對象,其實就是Bundle對象的集合,然后通過向集合內(nèi)部注冊多個Bundle;每個Bundle對應著多個靜態(tài)文件,可以想象成就是鍵值對集合;通過后面的Include方法包含N多個靜態(tài)文件,這里的靜態(tài)文件路徑可以是符合特定規(guī)則的字符串,由它內(nèi)部去計算;

這是注冊階段,然后就是使用階段,使用階段很簡單只要我們通過我們注冊的Key字符串就能直接引用這些靜態(tài)文件列表;

ASP.NET組件System.Web.Optimization運行原理的示例分析

我們只要關注Styles.Render、Scripts.Render兩個方法,這兩個方法是想頁面注入之前在后臺配置的靜態(tài)文件列表;這樣我們在客戶端看見的就是被捆綁過后的文件集合了;

ASP.NET組件System.Web.Optimization運行原理的示例分析

文件的連接地址已經(jīng)是被捆綁過后的地址了,這個地址就是我們在之前注冊的時候用的key,后面它需要這個key去獲取value 靜態(tài)文件列表;要想你的捆綁起效果需要在注冊的時候加上一段:BundleTable.EnableOptimizations = true;代碼,意思是說開啟捆綁,如果不開啟捆綁則默認在調(diào)試環(huán)境里將不起效果,因為System.Web.Optimization使用了默認捆綁策略,如果是在Debug模式下,將不啟用捆綁,如果你人為的設置了將覆蓋默認設置;

使用就是這些,下面我們需要搞懂它是如何運行的,要了解一下它的基本原理;

3】System.Web.Optimization 組件基本原理

既然IIS集成了管道模型,那么我們肯定是能找到對應的HttpModule的,為了節(jié)省時間我就不去下載源碼了,我們直接用反編譯工具看一下;

ASP.NET組件System.Web.Optimization運行原理的示例分析

這就是Bundle的HttpModule,它只用來處理
Bundle的連接地址,雖然它在HTTP的管道中;找到它就好順藤摸瓜了,但是奇怪的是我在Web.config里沒有發(fā)現(xiàn)它的配置信息,奇怪了,難道它還跑去系統(tǒng)文件改,當然是不可能的;所以我一時還想不起能有什么辦法動態(tài)注冊,提起動態(tài)注冊突然有了思路,好像有一個Assembly級別的特性用來注冊Application_Start啟動時候的前置代碼,會在Application啟動之前執(zhí)行,來看一下;

ASP.NET組件System.Web.Optimization運行原理的示例分析

果然藏著這里呢,它注冊了一個PreApplicationStartCode靜態(tài)類,使用Start方法啟動;

ASP.NET組件System.Web.Optimization運行原理的示例分析

這段代碼很簡單,先判斷有沒有執(zhí)行過注冊,如果沒有就執(zhí)行動態(tài)注冊,這個動態(tài)注冊組件是.NETFramework自帶的,在Microsoft.Web.Infrastructure里面只不過屬于平臺相關的,跟ASP.NET沒有直接關系,我們可以用Microsoft.Web.Infrastructure來開發(fā)自己的WEB組件;這里有一個疑問,為什么靜態(tài)方法也要加判斷呢,不是只會執(zhí)行一次嗎,因為靜態(tài)方法的執(zhí)行是不受控制的,所以如果不加判斷很有可能會注冊多次,出于嚴謹考慮還是加上;

現(xiàn)在基本上我們已經(jīng)找到源頭了,服務端這里我們先放一下,對于客戶端的疑問很多,它既然幫我們捆綁了,那么緩存是如何處理的,也就是說它的輸出緩存有沒有設置,如果設置了不是有問題;

【客戶端緩存相關】

為了很好的了解請求之間的信息,我們用Fiddler監(jiān)聽一下;

ASP.NET組件System.Web.Optimization運行原理的示例分析

我們看見它的Cache部分是用了If-Modified-Since來表示本地的文件的最后一次修改,這樣是為了能夠讓服務器去驗證文件是否改動,如果沒有改動服務器的響應狀態(tài)碼為304,說明Bundle在輸出的時候并沒有設置對這個文件進行客戶端強制緩存,我們通過Pragma: no-cache頭也能看出來了;

那么我們得出結論,所有Bundle出來的文件都不可能直接緩存在瀏覽器中,每次都會帶上Cache段If-Modified-Since去驗證服務器的文件版本;剛好這里我們可以跟動態(tài)輸出的靜態(tài)文件地址的后面的參數(shù)對上了;

比如:

/Content/css?v=ZPnWVRT3c0yyrVDPmI-xkJuhBdJfQsL3A0K5C9WTOk01

這個鏈接后面的v參數(shù)是表示當前Bundle后虛擬文件的版本,如果我們在服務器上把文件修改了之后那么這個文件的If-Modified-Since驗證就失敗了,會生成新的版本號作為連接的參數(shù);我們來看一下,心里踏實;

ASP.NET組件System.Web.Optimization運行原理的示例分析

我加了一個width:auto的style,那么這個時候我刷新客戶端應該是不會再有304出現(xiàn)了;

顯然/Content/css?v=doYFOk3BdOYWDIRbQ7juV6eQdlJAu6RtC0G13El7X041 文件的版本變了,那么Response也不應該是304了;

ASP.NET組件System.Web.Optimization運行原理的示例分析

ASP.NET組件System.Web.Optimization運行原理的示例分析

如果靜態(tài)文件的版本號發(fā)生改變,根本就不會帶上 If-Modified-Since,這個是用在每次進行進行Post是用來驗證的;其實意思就是說如果沒有IIS集成模式那么捆綁文件的方式只能改變靜態(tài)文件的文件名;

4】擴展自定義類型靜態(tài)文件

Bundle對象是所有需要捆綁文件的基類,如果我們需要擴展一些靜態(tài)文件,如一些特定領域的靜態(tài)文件,我們可以直接繼承這個類;

【XML文件的緩存】

擴展XML文件很簡單,我們只需要繼承一下Bundle對象,所有關于動態(tài)生成URL都有專門的對象處理,我們來看下代碼;

public class XmlBundle : Bundle
 {
 public XmlBundle(string path) : base(path) { }
 }
 public static class XmlBundleRender
 {
 public static IHtmlString Render(string path)
 {
  BundleResolver bundle = new BundleResolver(BundleTable.Bundles);
  return new HtmlString(
  string.Format(@"<link href=""{0}"" rel=""stylesheet""/>", bundle.GetBundleUrl(path)));
 }
 }

首先我們需要一個繼承自Bundle對象的XmlBundle,用來表示我們所有將要傳輸?shù)腦ML文件捆綁容器,然后我們需要一個靜態(tài)方法用來注冊捆綁后的URL;

這個URL的生成有專門的BundleResolver對象來完成,我們只需要傳入所有的BundleCollection對象,我這里為了能在瀏覽器中測試所以寫了一段stylesheet類型的link;這樣我們就能直接在我們需要的地方直接使用了,我在index視圖中引用:@MvcApplication4.Seed.XmlBundleRender.Render("~/custom/xml");是不是很簡單,這樣我們就能對所有想控制捆綁的文件進行捆綁,只需要繼承加簡單的靜態(tài)方法輔助;

我們來看一下我們的XML文件是否具有所有緩存特性;

ASP.NET組件System.Web.Optimization運行原理的示例分析

第一次請求沒有加If-Modified-Since段,返回的內(nèi)容是一個簡單的<model>222</model> 測試簡單,現(xiàn)在我們看它是否在下一次不改變內(nèi)容的情況下使用緩存;

ASP.NET組件System.Web.Optimization運行原理的示例分析

在我們預料之中,使用了緩存數(shù)據(jù),下面我們需要把服務器上的XML文件進行修改,將222改成243454637看是否自動刷新本地緩存也就是說不會是304返回狀態(tài);

ASP.NET組件System.Web.Optimization運行原理的示例分析

也刷新緩存,符合理論根據(jù),正確的返回了我們修改后的值;

感謝你能夠認真閱讀完這篇文章,希望小編分享的“ASP.NET組件System.Web.Optimization運行原理的示例分析”這篇文章對大家有幫助,同時也希望大家多多支持億速云,關注億速云行業(yè)資訊頻道,更多相關知識等著你來學習!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。

AI