大多數瀏覽器會對同一域名的請求限制請求數量,通常是在8個之內。每次最多能夠同時請求8個,要是資源多於8個,那麼剩下的就要排隊等待請求了。因此爲了提升首次加載頁面的速度。提升請求併發請求數量,下降請求次數就是一個很重要的點。javascript
Asp.Net MVC4和.NET Framework4.5提供了支持捆綁和壓縮的新類庫System.Web.Optimization
。css
該類庫提供了以下特性:html
在App_Start
文件中新增一個BundleConfig.cs
文件。實現靜態RegisterBundles
方法。該方法用來建立,註冊和配置bundle。(在該目錄下代碼最好把他們的命名空間去掉 ".App_Start",保持一個統一的高等級的命名空間)。java
調用BundleCollection.Add()
方法添加捆綁資源,該方法參數爲ScriptBundle
或StyleBundle
。jquery
ScriptBundle
和StyleBundle
須要傳遞一個虛擬路徑給構造函數。該虛擬路徑其實就是該捆綁的名稱或者標識符。因此該虛擬路徑能夠任意設置,並不須要匹配物理路徑。Bundle
的Include
方法包含一個或者多個腳本。ajax
經過引用該虛擬路徑就可使用這些捆綁的資源@Script.Render("~/bundles/jquery")
。編程
Debug模式下默認沒有開啓捆綁和壓縮,發佈模式下默認是開啓的。數組
public static void RegisterBundles(BundleCollection bundles) { //該值爲true,在任何模式下都使用捆綁和壓縮。 //BundleTable.EnableOptimizations = true; //添加名稱爲「~/bundles/jquery」腳本捆綁 bundles.Add(new ScriptBundle("~/bundles/jquery").Include("~/Scripts/jquery-{version}.js")); //添加名稱爲「~/Content/css」樣式捆綁 bundles.Add(new StyleBundle("~/Content/css").Include("~/Content/Site.css")); }
使用{version}
佔位符能夠在使用NuGet更新Jquery版本時,不須要更新Bundle的引用,自動使用最新的Jquery版本。瀏覽器
ScriptBundle
和StyleBundle
的Include
方法參數是一個字符串類型的數組,因此一個Bundle實例能夠添加多個文件。緩存
如
bundles.Add(new StyleBundle("~/Content/css").Include( "~/Content/themes/base/jquery.ui.core.css", "~/Content/themes/base/jquery.ui.resizable.css", "~/Content/themes/base/jquery.ui.selectable.css", "~/Content/themes/base/jquery.ui.accordion.css", "~/Content/themes/base/jquery.ui.autocomplete.css", "~/Content/themes/base/jquery.ui.button.css", "~/Content/themes/base/jquery.ui.dialog.css", "~/Content/themes/base/jquery.ui.slider.css", "~/Content/themes/base/jquery.ui.tabs.css", "~/Content/themes/base/jquery.ui.datepicker.css", "~/Content/themes/base/jquery.ui.progressbar.css", "~/Content/themes/base/jquery.ui.theme.css"));
可是Bundle類也提供了IncludeDirectory
方法,能夠添加指定目錄下的指定文件。
//添加Content/themes/base目錄下的全部css文件 bundles.Add(new StyleBundle("~/Content/css"").IncludeDirectory("~/Content/themes/base", "*.css"));
使用通配符要注意:
在Global.asax的Appliaction_Start方法中調用以前的定義的方法,BundleConfig.RegisterBundles(BundleTable.Bundles)
啓用Bundle。
public class MvcApplication : System.Web.HttpApplication { protected void Application_Start() { BundleConfig.RegisterBundles(BundleTable.Bundles); } }
若是咱們須要在頁面中使用這些資源時。能夠經過Styles和Scripts來引入。若是要使用捆綁的Style,能夠在頁面中添加@Styles.Render("~/Content/css")
。若是要使用捆綁的Script,能夠在頁面中添加@Script.Render("~/bundles/jquery")
。
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>@ViewBag.Title - 個人 ASP.NET 應用程序</title> //引入樣式捆綁 @Styles.Render("~/Content/css") </head> <body> <div class="container body-content"> @RenderBody() <hr /> <footer> <p>© @DateTime.Now.Year - 個人 ASP.NET 應用程序</p> </footer> </div> //引入js捆綁 @Scripts.Render("~/bundles/jquery") @RenderSection("scripts", required: false) </body> </html>
能夠把CSS樣式文件置頂,JavaScript文件置底,來優化網頁。可是modernizr.js
文件要放在頁面頂部,由於有些樣式文件須要。
Bundle對CDN也提供了很好的支持。
public static void RegisterBundles(BundleCollection bundles) { //bundles.Add(new ScriptBundle("~/bundles/jquery").Include( // "~/Scripts/jquery-{version}.js")); bundles.UseCdn = true; //啓用cdn //添加地址 var jqueryCdnPath = "http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.7.1.min.js"; bundles.Add(new ScriptBundle("~/bundles/jquery",jqueryCdnPath).Include("~/Scripts/jquery-{version}.js")); }
在使用CDN時,要應對沒有獲取到資源的狀況。
@Scripts.Render("~/bundles/jquery") <script type="text/javascript"> if (typeof jQuery == 'undefined') { var e = document.createElement('script'); e.src = '@Url.Content("~/Scripts/jquery-1.7.1.js")'; e.type = 'text/javascript'; document.getElementsByTagName("head")[0].appendChild(e); } </script>
瀏覽器是根據URL來緩存數據的。瀏覽器不管什麼時候請求資源,都會根據URL來檢查緩存裏是否包含了該資源文件。若是包含了,瀏覽器就不會再去請求,而是使用緩存的文件,來渲染。
Bundle機制使咱們每次修改資源文件時都會在URL後自動添加一個哈希值,從而避免瀏覽器緩存,不能及時更新資源的狀況。
v=******,後面的值就是哈希值。Bundle
在Debug模式下默認是沒有開啓的。在發佈模式下才會開啓。可是咱們能夠在BundleConfig下添加BundleTable.EnableOptimizations = true;
開啓捆綁模式。
一個Bundle
通常包含多個文件,若是咱們只是修改了其中的一個文件,那麼Bundle
的哈希值也會改變,就會更新Bundle
的全部文件。
捆綁和縮小主要下降了第一次訪問頁面時加載的時間。此時靜態資源就會被緩存起來(js,css,圖片)。當訪問其餘頁面,且該頁面的資源地址和第一次訪問的地址相同時,就會從緩存裏獲取,再也不向服務端獲取。
若是資源過多,使用CDN,比使用Bundle
更有效。固然Bundle
也能夠結合CDN使用。 經過使用CDN,能夠減輕每一個主機名8個併發鏈接的瀏覽器限制。由於CDN的主機名與您的主機站點不一樣,CDN上的資產請求不會與您的主機環境的8個併發鏈接數計數。
Bundle
最好按照功能來區分捆綁。例如,默認的ASP.Net應用程序的NET MVC模板建立了一個與jQuery分離的jQuery驗證包。由於所建立的默認視圖輸入輸出值,因此它們須要驗證包。
若有不對,請多多指教。
參考: