背景javascript
做爲web開發人員你們大多瞭解一些網站的性能優化方法,其實大部分方法都不復雜,例如針對前端js和css的壓縮來減小請求大小,經過合併來減小請求次數。這裏站在.Net後端程序員的角度來看一下如何最簡單快捷的處理這一類需求。css
全文分3節 combres,mvc4的Bundle,以及2者的對比和我的的意見觀點。前端
Combresjava
Combres是一個.NET程序庫,可以縮小,壓縮,合併,以及緩存的JavaScript和CSS資源,ASP.NET和ASP.NET MVC的Web應用程序。簡單地說,它能夠幫助您的應用程序更好的頁面加載速度。jquery
源代碼存在 https://github.com/buunguyen/combresgit
經過nuget添加combres很是簡單程序員
加載完成後 .Net3.5的同窗須要按照combres.readme的指導,首先刪除掉AppStart_Combres.cs而後在global.asax中添加Combres引用,而後在
githubRegisterRoutes()
或者 Application_Start()添加方法RouteTable.Routes.AddCombresRoute("Combres")
.Net4.0的同窗能夠忽略這一步,大家會在發現nuget包安裝程序(下面簡稱包管理)已經自動幫大家生成了這樣一段代碼web
public static class Combres { public static void PreStart() { RouteTable.Routes.AddCombresRoute("Combres"); } }
下面最主要的就是就是配置combres.xml,至於webconfig的配置包管理已經幫你們設置完成。後端
爲了方便測試,咱們建個白板頁面,而後添加最簡單的js文件和css文件。
那麼下面來看測試效果,咱們先建一個簡單的測試頁面。
@{ ViewBag.Title = "Home Page"; } <script src="~/Scripts/Demo/JScript1.js" type="text/javascript"></script> <script src="~/Scripts/Demo/JScript2.js" type="text/javascript"></script> <script src="~/Scripts/Demo/JScript3.js" type="text/javascript"></script> <link href="~/Content/Demo/StyleSheet1.css" rel="stylesheet" type="text/css" /> <link href="~/Content/Demo/StyleSheet2.css" rel="stylesheet" type="text/css" /> <link href="~/Content/Demo/StyleSheet3.css" rel="stylesheet" type="text/css" />
打開fiddler查看頁面請求。
而後咱們使用combres修改頁面代碼
mvc:
1 @using Combres.Mvc 2 @{ 3 ViewBag.Title = "Home Page"; 4 } 5 @Url.CombresLink("siteCss") 6 @Url.CombresLink("siteJs")
webform:
1 <%= WebExtensions.CombresLink("siteJs") %> 2 <%= WebExtensions.CombresLink("siteCss") %>
再來查看頁面請求
請求次數變爲了2次,大小也被壓縮的很是低。
Combres的實現原理不復雜,服務器端先加載配置緩存起來,根據配置節點生成hash值,具體實現以下
1 public string Generate(ResourceSet rs) 2 { 3 if (Log.IsDebugEnabled) 4 Log.Debug("Computing hash for set " + rs.Name + ". Current hash: " + rs.Hash); 5 6 var contributingFactors = new List<object> {rs.DebugEnabled}; 7 rs.Filters.ToList().ForEach(contributingFactors.Add); 8 rs.CacheVaryProviders.ToList().ForEach(contributingFactors.Add); 9 rs.Resources.ToList().ForEach(r => 10 { 11 contributingFactors.Add(r.ReadFromCache(true)); 12 contributingFactors.Add(r.ForwardCookie); 13 contributingFactors.Add(r.Mode); 14 contributingFactors.Add(r.Minifier); 15 }); 16 var hash = contributingFactors.Select(f => f.GetHashCode()) 17 .Aggregate(17, (accum, element) => 31 * accum + element) 18 .ToString(); 19 20 if (Log.IsDebugEnabled) 21 Log.Debug("New hash: " + hash); 22 return hash; 23 }
得出來的值就是咱們上面看到的combres.xsd/setname/hashvalue中的hashvalue,當咱們請求產生的時候會由一個CombresHandler根據hashvalue來獲取對應的資源而且進行合併壓縮。
處理流程首先判斷你的瀏覽器是否支持壓縮,經過Context.Request.Headers["Accept-Encoding"]。
若是判斷爲接受combres會對資源進行2層壓縮,咱們這裏簡單稱只爲minifier和gzip。
若是瀏覽器不支持壓縮那麼gzip這一層會被忽略,minifier的壓縮方法使用YuiJSMinifier和YuiCssMinifier,方法依賴雅虎的開源組件Yahoo.Yui.Compressor
handler會爲新的請求生成一個cachekey:「Combres/Combres.RequestProcessor/siteJs/1342767128/gzip」
和etag key「Combres/Combres.RequestProcessor/siteJs/1342767128/gzip/@etag」(實際上真正存於Context.Response.Cache的ETag是"1342767128")
分別對應服務器端緩存和瀏覽器緩存,當下次請求已經發現有key存在,便從緩存中直接獲取資源或者直接304。
根據結果圖來看,combres確實是一款很不錯的工具。
MVC4的Bundle
MVC4之後自帶了Bundling和Minification。操做也很簡單,新建一個mvc4項目。在App_Start文件夾下找到BundleConfig.cs。
添加以下代碼:
1 public static void RegisterBundles(BundleCollection bundles) 2 { 3 4 bundles.Add(new ScriptBundle("~/bundles/jquerydemo").Include( 5 "~/Scripts/Demo/JScript1.js", 6 "~/Scripts/Demo/JScript2.js", 7 "~/Scripts/Demo/JScript3.js")); 8 9 bundles.Add(new StyleBundle("~/Content/cssdemo").Include( 10 "~/Content/Demo/StyleSheet1.css", 11 "~/Content/Demo/StyleSheet2.css", 12 "~/Content/Demo/StyleSheet3.css")); 13 }
頁面端添加:
1 @Styles.Render("~/Content/cssdemo") 2 @Scripts.Render("~/bundles/jquerydemo")
而後記住在BundleConfig.cs添加BundleTable.EnableOptimizations = true;否則MVC4不會啓用壓縮,減小請求數量和帶寬。
咱們來看一下效果圖:
請求次數減小,也有壓縮。可是比起combres效率要差了一些。可是這樣未必就是說combres要更好。
對比
2者相比較而已combres的效率要高一些,可是mvc4做爲原生自帶的功能,對於版本管理比較苛刻的系統仍是具備優點,而且對於大型項目還要涉及到cdn問題。
目前combres是不支持cdn的,雖然做者給出了相關的話題,可是做者本人最後還有給出了不是使人滿意的答覆。
相對MVC4的Bundle是支持cdn的,只須要在對應節點添加 bundles.UseCdn = true便可。
因此根據各自項目不一樣的場景,酌情處理吧。
我的推薦靜態資源的壓縮和合並儘可能在前端就作掉,例如grunt。這樣無論是cdn仍是部署發佈都更合理沒有必要再浪費後端的處理資源。
本篇先到此,但願對你們有幫助!