MAQNH

记录开发过程中的点点滴滴。

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

原文地址:https://go.microsoft.com/fwlink/?LinkId=301862

Bundling and minification are two techniques you can use in ASP.NET 4.5 to improve request load time. Bundling and minification improves load time by reducing the number of requests to the server and reducing the size of requested assets (such as CSS and JavaScript.)

在Asp.Net4.5中,为了改善请求加载时间,你可能使用到两个技术:捆绑和压缩。绑定和压缩通过减少对服务的请求次数和减少请求资源(如css和js)的大小的方式来改善请求加载时间。

Most of the current major browsers limit the number of simultaneous connections per each hostname to six. That means that while six requests are being processed, additional requests for assets on a host will be queued by the browser. In the image below, the IE F12 developer tools network tabs shows the timing for assets required by the About view of a sample application.

当前大多数主流浏览器会把对同一主机的并发连接数限制在6个。这意味着针对一个主机的正在处理的连接数达到六个以后,浏览器会将新增的资源请求排队。如下图,在IE浏览器的F12开发者工具中的Network标签页中可以看到对示例应用程序的About页面进行访问时,各个资源请求的耗时情况。

B/M

The gray bars show the time the request is queued by the browser waiting on the six connection limit. The yellow bar is the request time to first byte, that is, the time taken to send the request and receive the first response from the server. The blue bars show the time taken to receive the response data from the server. You can double-click on an asset to get detailed timing information. For example, the following image shows the timing details for loading the /Scripts/MyScripts/JavaScript6.js file.

灰色条显示了因为六个链接限制,而被浏览器排队的请求的等待时间。黄色条表示第一个字符的时间,即发送请求并从服务器接收到第一个响应所花费的时间。蓝色条表示从服务器接收响应数据所花费的时间。你可以双击一个资源查看详细的时间花费信息。比如,下图显示了加载/Scripts/MyScripts/JavaScript6.js 文件所花费的时间明细。

The preceding image shows the Start event, which gives the time the request was queued because of the browser limit the number of simultaneous connections. In this case, the request was queued for 46 milliseconds waiting for another request to complete.

通过上图可以看出,因为浏览器对并发连接的数目限制,该请求花费在排队上的时间。在这个例子中,该请求在队列中等待了46毫秒直到另一个请求完成。

Bundling 捆绑

Bundling is a new feature in ASP.NET 4.5 that makes it easy to combine or bundle multiple files into a single file. You can create CSS, JavaScript and other bundles. Fewer files means fewer HTTP requests and that can improve first page load performance.

绑定是Asp.Net4.5的一个新功能,该功能可以很容易的把多个文件联合或者捆绑成一个单独的文件。你可以创建Css,js或者其他软件集。文件越少,Http请求就越少,从而优化首页的加载性能。

The following image shows the same timing view of the About view shown previously, but this time with bundling and minification enabled.

启用捆绑和压缩功能以后,再次访问示例应用程序的About页面,下图显示此处的时序视图。

Minification 压缩

Minification performs a variety of different code optimizations to scripts or css, such as removing unnecessary white space and comments and shortening variable names to one character. Consider the following JavaScript function.

压缩功能对scripts和css执行各种不同的代码优化,例如去除不必要的空格、注释,缩减变量名为一个字符。考虑下面的js函数。

AddAltToImg = function (imageTagAndImageID, imageContext) {
    ///<signature>
    ///<summary> Adds an alt tab to the image
    // </summary>
    //<param name="imgElement" type="String">The image selector.</param>
    //<param name="ContextForImage" type="String">The image context.</param>
    ///</signature>
    var imageElement = $(imageTagAndImageID, imageContext);
    imageElement.attr('alt', imageElement.attr('id').replace(/ID/, ''));
}

After minification, the function is reduced to the following:压缩以后,该函数被缩减成下面这样

AddAltToImg = function (n, t) { var i = $(n, t); i.attr("alt", i.attr("id").replace(/ID/, "")) }

In addition to removing the comments and unnecessary whitespace, the following parameters and variable names were renamed (shortened) as follows:

除了去除注释和不必要的空格,下列参数和变量名也被重命名:

OriginalRenamed
imageTagAndImageID n
imageContext t
imageElement i

Impact of Bundling and Minification 捆绑和压缩的影响

The following table shows several important differences between listing all the assets individually and using bundling and minification (B/M) in the sample program.

下表显示了示例程序在使用压缩技术前后的几点重要的不同之处:

 Using B/MWithout B/MChange
File Requests 9 34 256%
KB Sent 3.26 11.92 266%
KB Received 388.51 530 36%
Load Time 510 MS 780 MS 53%

The bytes sent had a significant reduction with bundling as browsers are fairly verbose with the HTTP headers they apply on requests. The received bytes reduction is not as large because the largest files (Scripts\jquery-ui-1.8.11.min.js and Scripts\jquery-1.7.1.min.js) are already minified. Note: The timings on the sample program used the Fiddler tool to simulate a slow network. (From the Fiddler Rules menu, select Performance then Simulate Modem Speeds.)

浏览器在发送字段的时候通过捆绑有一个很大的缩减,因为包含在请求中的http头文件是很冗长的。但是接收字段的缩减就不是很明显了,因为最大的文件(Scripts\jquery-ui-1.8.11.min.js and Scripts\jquery-1.7.1.min.js)已经是最小的了。注意:示例程序的时间是通过Fiddler工具模拟一个较慢的网络获得的(在fiddler规则菜单中,选择 performance 然后选择 Simulate Modem Speeds)。

Debugging Bundled and Minified JavaScript 调试绑定和压缩javascript

It's easy to debug your JavaScript in a development environment (where the compilation Element in the Web.config file is set to debug="true" ) because the JavaScript files are not bundled or minified. You can also debug a release build where your JavaScript files are bundled and minified. Using the IE F12 developer tools, you debug a JavaScript function included in a minified bundle using the following approach:

在开发环境中调试javascript很容易(在web.config中的编译要素下设置debug="true"),因为javascript文件是未捆绑未压缩的。你也可以调试发布版本,尽管其中的javascript是捆绑压缩过的。使用IE的F12开发者工具,可以下列方式调试一个包含在压缩过的js函数:

  1. Select the Script tab and then select the Start debugging button.选择Script标签页,点击Start debugging按钮。
  2. Select the bundle containing the JavaScript function you want to debug using the assets button.通过资源按钮选择你想调试的javascript函数
  3. Format the minified JavaScript by selecting the Configuration button , and then selecting Format JavaScript.点击Configuration button按钮格式化压缩的javascript,然后选择格式化以后的js。
  4. In the Search Scrip t input box, select the name of the function you want to debug. In the following image, AddAltToImg was entered in the Search Scrip t input box.在搜索框中,输入你要调试的js函数的名字。在下图中,在搜索框中输入AddAltToImg

For more information on debugging with the F12 developer tools, see the MSDN article Using the F12 Developer Tools to Debug JavaScript Errors.

更多关于调试的信息,查看Using the F12 Developer Tools to Debug JavaScript Errors.

Controlling Bundling and Minification 控制捆绑和压缩

Bundling and minification is enabled or disabled by setting the value of the debug attribute in the compilation Element in the Web.config file. In the following XML, debug is set to true so bundling and minification is disabled.

通过设置web.config编译元素中的debug属性启动或者关闭捆绑压缩功能。在下面的xml中,debug被设置为真,从而关闭捆绑压缩功能。

<system.web>
    <compilation debug="true" />
    <!-- Lines removed for clarity. -->
</system.web>

To enable bundling and minification, set the debug value to "false". You can override the Web.config setting with the EnableOptimizations property on the BundleTable class. The following code enables bundling and minification and overrides any setting in the Web.config file.

要启用捆绑压缩功能,设置debug="false"。可以通过BundleTable类的EnableOptimizations属性重写web.config设置。下列代码启用捆绑压缩,可以重置web.config中的相关设置。

 

public static void RegisterBundles(BundleCollection bundles)
{
    bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
                 "~/Scripts/jquery-{version}.js"));

    // Code removed for clarity.
    BundleTable.EnableOptimizations = true;
}
Note

Unless EnableOptimizations is true or the debug attribute in the compilation Element in the Web.config file is set to false, files will not be bundled or minified. Additionally, the .min version of files will not be used, the full debug versions will be selected. EnableOptimizations overrides the debug attribute in the compilation Element in the Web.config file

EnableOptimizations为true并且web.comfig文件中compilation Element的debug属性设置成false,文件才会被捆绑压缩。此外,.min版本的文件不会被采用,将选择完整的调试版本。(什么意思?)。EnableOptimizations覆盖web.config中的dubug属性。(这段理解好像有问题。)

 Using Bundling and Minification with ASP.NET Web Forms and Web Pages 在Asp.Net webForms 和WebPages中使用捆绑压缩

Using Bundling and Minification with ASP.NET MVC 在Asp.Net MVC中使用捆绑压缩

In this section we will create an ASP.NET MVC project to examine bundling and minification. First, create a new ASP.NET MVC internet project named MvcBM without changing any of the defaults.

在这一节我们将创建一个Asp.net MVC项目检查捆绑压缩功能。首先,创建一个asp.net mvc项目,命名为MvcBM,先不要做任何修改。

Open the App_Start\BundleConfig.cs file and examine the RegisterBundles method which is used to create, register and configure bundles. The following code shows a portion of the RegisterBundles method.

打开App_Start\BundleConfig.cs文件,检查RegisterBundles方法,该方法用来创建、注册并配置捆绑。下面的代码显示了RegisterBundles方法的一部分。

public static void RegisterBundles(BundleCollection bundles)
{
     bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
                 "~/Scripts/jquery-{version}.js"));
         // Code removed for clarity.
}

The preceding code creates a new JavaScript bundle named ~/bundles/jquery that includes all the appropriate (that is debug or minified but not .vsdoc) files in the Scripts folder that match the wild card string "~/Scripts/jquery-{version}.js". For ASP.NET MVC 4, this means with a debug configuration, the file jquery-1.7.1.js will be added to the bundle. In a release configuration, jquery-1.7.1.min.js will be added. The bundling framework follows several common conventions such as:

前面的代码创建了一个名字为"~/bundles/jquery"的js包,其中包含Scripts文件夹中所有匹配通配符“~/Scripts/jquery-{version}.js”的文件。对于mvc4来说,这意味着在调试配置下 jquery-1.7.1.js将被添加到包中。在发布配置中,jquery-1.7.1.min.js将被添加到保证。捆绑框架遵守几个通用的约定:

    • Selecting ".min" file for release when "FileX.min.js" and "FileX.js" exist. 在发布版本中,当fileX.min.js和fileX.js共存时,选择.min文件
    • Selecting the non ".min" version for debug. 在调试版本中,选择没有.min 的文件。
    • Ignoring "-vsdoc" files (such as jquery-1.7.1-vsdoc.js), which are used only by IntelliSense.忽略 -vsdoc 文件,该类文件只有在智能感知的时候有用。

The {version} wild card matching shown above is used to automatically create a jQuery bundle with the appropriate version of jQuery in your Scripts folder. In this example, using a wild card provides the following benefits:

上面显示的“{version}”通配符用来自动创建一个包含scripts文件夹下匹配版本的jquery包。在这个例子中,使用通配符提供了以下有点:

    • Allows you to use NuGet to update to a newer jQuery version without changing the preceding bundling code or jQuery references in your view pages.在不修改之前捆绑代码和view视图中jquery引用的情况下,通过Nuget升级到一个新的jquery版本
    • Automatically selects the full version for debug configurations and the ".min" version for release builds.自动为调试配置选择完整版本,为发布配置选择".min"版本。

Using a CDN 

The follow code replaces the local jQuery bundle with a CDN jQuery bundle. 下列代码使用内容分发网络jquery包替代本地jquery包

public static void RegisterBundles(BundleCollection bundles)
{
    //bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
    //            "~/Scripts/jquery-{version}.js"));

    bundles.UseCdn = true;   //enable CDN support

    //add link to jquery on the 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"));

    // Code removed for clarity.
}

In the code above, jQuery will be requested from the CDN while in release mode and the debug version of jQuery will be fetched locally in debug mode. When using a CDN, you should have a fallback mechanism in case the CDN request fails. The following markup fragment from the end of the layout file shows script added to request jQuery should the CDN fail.

在上面的代码中,发布模式下,jquery从CDN获取;调试模式下,从本地获取调试版本的jquery。当使用CDN时,需要有一个后备机制,以防CDN请求失败。以下标记片段位于布局文件的结尾处,其显示了当CDN请求失败后,向要求的jquery中添加脚本。

</footer>

        @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> 

        @RenderSection("scripts", required: false)
    </body>
</html>

Creating a Bundle

The Bundle class Include method takes an array of strings, where each string is a virtual path to resource. The following code from the RegisterBundles method in the App_Start\BundleConfig.cs file shows how multiple files are added to a bundle:

Bundle类的Include方法接受一个字符串数组,每个字符串都是一个资源虚拟路径。App_Start\BundleConfig.cs中的ResisterBundles方法显示了如何把多个文件添加到捆绑包中:

bundles.Add(new StyleBundle("~/Content/themes/base/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"));

The Bundle class IncludeDirectory method is provided to add all the files in a directory (and optionally all subdirectories) which match a search pattern. The Bundle class IncludeDirectory API is shown below:

Bundle类的IncludeDirectory方法能够把与查询模版匹配的目录(任意子目录)的所有文件都添加到捆绑包中。IncludeDirectoryde API如下:

public Bundle IncludeDirectory(
    string directoryVirtualPath,  // The Virtual Path for the directory.
    string searchPattern)         // The search pattern.

public Bundle IncludeDirectory(
    string directoryVirtualPath,  // The Virtual Path for the directory.
    string searchPattern,         // The search pattern.
    bool searchSubdirectories)    // true to search subdirectories.

Bundles are referenced in views using the Render method, ( Styles.Render for CSS and Scripts.Render for JavaScript). The following markup from the Views\Shared\_Layout.cshtml file shows how the default ASP.NET internet project views reference CSS and JavaScript bundles.

在视图中通过Render方法引用Bundles,(css使用Style.Render,js使用Scripts.Render).下面是一段来自于Views\Shared\_Layout.cshtml的代码,从中我们可以看到在Asp.net网站项目中的默认视图中是如引用css和js捆绑包的。

<!DOCTYPE html>
<html lang="en">
<head>
    @* Markup removed for clarity.*@    
    @Styles.Render("~/Content/themes/base/css", "~/Content/css")
    @Scripts.Render("~/bundles/modernizr")
</head>
<body>
    @* Markup removed for clarity.*@
   
   @Scripts.Render("~/bundles/jquery")
   @RenderSection("scripts", required: false)
</body>
</html>

Notice the Render methods takes an array of strings, so you can add multiple bundles in one line of code. You will generally want to use the Render methods which create the necessary HTML to reference the asset. You can use the Url method to generate the URL to the asset without the markup needed to reference the asset. Suppose you wanted to use the new HTML5 async attribute. The following code shows how to reference modernizr using the Url method.

注意Render方法接受一组字符串,这意味着你可以在一行代码中添加多个捆绑包。你通常会使用创建必要Heml的Render方法去引用资源。你可以使用Url方法生成资源的URL,而不需要引用资源的标记。如果你想要使用Html5中的async属性。下面的代码显示了如何使用Url方法去引用modernizr

<head>
    @*Markup removed for clarity*@
    <meta charset="utf-8" />
    <title>@ViewBag.Title - MVC 4 B/M</title>
    <link href="~/favicon.ico" rel="shortcut icon" type="image/x-icon" />
    <meta name="viewport" content="width=device-width" />
    @Styles.Render("~/Content/css")

   @* @Scripts.Render("~/bundles/modernizr")*@

    <script src='@Scripts.Url("~/bundles/modernizr")' async> </script>
</head>

 

Using the "*" Wildcard Character to Select Files 使用‘*’通配符选择文件

The virtual path specified in the Include method and the search pattern in the IncludeDirectory method can accept one "*" wildcard character as a prefix or suffix to in the last path segment. The search string is case insensitive. The IncludeDirectory method has the option of searching subdirectories.

Include方法中的虚拟路径和IncludeDirectory方法中的搜索模版可以使用‘*’通配符作为最后一个路径段的前缀或者后缀。查询字段对大小写不敏感。IncludeDirectory方法可以设置是否搜索子目录。

Consider a project with the following JavaScript files:考虑包含一下js文件的项目:

    • Scripts\Common\AddAltToImg.js
    • Scripts\Common\ToggleDiv.js
    • Scripts\Common\ToggleImg.js
    • Scripts\Common\Sub1\ToggleLinks.js

The following table shows the files added to a bundle using the wildcard as shown:下表显示了使用通配符时被添加到捆绑包中的文件:

CallFiles Added or Exception Raised
Include("~/Scripts/Common/*.js") AddAltToImg.js, ToggleDiv.js, ToggleImg.js
Include("~/Scripts/Common/T*.js") Invalid pattern exception. The wildcard character is only allowed on the prefix or suffix.
Include("~/Scripts/Common/*og.*") Invalid pattern exception. Only one wildcard character is allowed.
"Include("~/Scripts/Common/T*") ToggleDiv.js, ToggleImg.js
"Include("~/Scripts/Common/*") Invalid pattern exception. A pure wildcard segment is not valid.
IncludeDirectory("~/Scripts/Common", "T*") ToggleDiv.js, ToggleImg.js
IncludeDirectory("~/Scripts/Common", "T*",true) ToggleDiv.js, ToggleImg.js, ToggleLinks.js

 

Explicitly adding each file to a bundle is generally the preferred over wildcard loading of files for the following reasons:首选通配符加载明确的文件到捆绑包中,原因如下:

    • Adding scripts by wildcard defaults to loading them in alphabetical order, which is typically not what you want. CSS and JavaScript files frequently need to be added in a specific (non-alphabetic) order. You can mitigate this risk by adding a custom IBundleOrderer implementation, but explicitly adding each file is less error prone. For example, you might add new assets to a folder in the future which might require you to modify your IBundleOrderer implementation.通过通配符加载文档默认是按照字母顺序加载的,这可能不是你想要的。Css和js通常需要以特定的顺序添加。你可以实现一个IBundleOrderer接口降低风险,但是明确添加每个文件使错误的可能性更小。例如:以后如果要添加一个新的资源到目录中,就不得不修改IbundleOrderer的实现。
    • View specific files added to a directory using wild card loading can be included in all views referencing that bundle. If the view specific script is added to a bundle, you may get a JavaScript error on other views that reference the bundle.把特定视图文件添加到一个用通配符载入的字典中,该文件将会包含在所有引用了该捆绑包的视图中。如果特定视图脚本添加到一个捆绑包中,在另一个引用了该捆绑包的视图中可能会出现一个js错误。
    • CSS files that import other files result in the imported files loaded twice. For example, the following code creates a bundle with most of the jQuery UI theme CSS files loaded twice.引用过其他文件的css文件可能导致被引用的文件被载入两次。例如,下面的代码创建一个捆绑包,其中大部分jQuery UI主题CSS文件加载了两次。

bundles.Add(new StyleBundle("~/jQueryUI/themes/baseAll")
    .IncludeDirectory("~/Content/themes/base", "*.css"))

 The wild card selector "*.css" brings in each CSS file in the folder, including the Content\themes\base\jquery.ui.all.css file. The jquery.ui.all.css file imports other CSS files.通配符选择器“*.css”导入文件夹下的每一个css文件,包括Content\themes\base\jquery.ui.all.css文件。该文件导入其他css文件。

Bundle Caching 捆绑缓存

Bundles set the HTTP Expires Header one year from when the bundle is created. If you navigate to a previously viewed page, Fiddler shows IE does not make a conditional request for the bundle, that is, there are no HTTP GET requests from IE for the bundles and no HTTP 304 responses from the server. You can force IE to make a conditional request for each bundle with the F5 key (resulting in a HTTP 304 response for each bundle). You can force a full refresh by using ^F5 (resulting in a HTTP 200 response for each bundle.)

捆绑包创建时,设置Http过期头为一年。如果你导航到之前的视图页,Fiddler显示IE没有发起对捆绑包的条件请求,也就是说,IE没有发起get请求,服务器也没有304响应。你可以通过F5键强制IE为每一个捆绑包发起条件请求(每个捆绑包得到一个http304响应)。也可以使用ctrl+F5完全强制刷新(每个捆绑包得到一个http200响应)。

The following image shows the Caching tab of the Fiddler response pane:下图显示Fiddler响应窗口的Caching标签页。

fiddler caching image

The request http://localhost/MvcBM_time/bundles/AllMyScripts?v=r0sLDicvP58AIXN_mc3QdyVvVj5euZNzdsa2N1PKvb81
is for the bundle AllMyScripts and contains a query string pair v=r0sLDicvP58AIXN_mc3QdyVvVj5euZNzdsa2N1PKvb81. The query string v has a value token that is a unique identifier used for caching. As long as the bundle doesn't change, the ASP.NET application will request the AllMyScripts bundle using this token. If any file in the bundle changes, the ASP.NET optimization framework will generate a new token, guaranteeing that browser requests for the bundle will get the latest bundle.

请求 http://localhost/MvcBM_time/bundles/AllMyScripts?v=r0sLDicvP58AIXN_mc3QdyVvVj5euZNzdsa2N1PKvb81获取捆绑包AllMyScripts并且包含一个查询字符串对v=r0sLDicvP58AIXN_mc3QdyVvVj5euZNzdsa2N1PKvb81.查询字符串v有一个token值,它是用于缓存的唯一标识符。只要捆绑包没有改变,Asp.Net一直使用该token请求AllMyScripts捆绑包。如果捆绑包中的任何文件被改变,Asp.Net优化框架将会生成一个新的token,确保浏览器能够获取最新的捆绑包。

If you run the IE9 F12 developer tools and navigate to a previously loaded page, IE incorrectly shows conditional GET requests made to each bundle and the server returning HTTP 304. You can read why IE9 has problems determining if a conditional request was made in the blog entry Using CDNs and Expires to Improve Web Site Performance.

如果你运行IE9 F12开发者工具并导航到之前载入的页面,IE会错误的显示对每个捆绑包的条件get请求以及服务器的304响应。你可以阅读博客 Using CDNs and Expires to Improve Web Site Performance 了解为什么IE9在决定是否发起一个条件请求时存在问题。

LESS, CoffeeScript, SCSS, Sass Bundling.

The bundling and minification framework provides a mechanism to process intermediate languages such as SCSS, Sass, LESS or Coffeescript, and apply transforms such as minification to the resulting bundle. For example, to add .less files to your MVC 4 project:

绑定和压缩框架提供了一种机制,该机制用来处理诸如SCSS,Sass,LESS或者Coffeescript这样的中间语言并将此类压缩转换为结果压缩包。例如,添加.less文件到你的MVC4项目:

  1. Create a folder for your LESS content. The following example uses the Content\MyLess folder.为LESS内容创建一个文件。下面这个例子使用文件夹Content\MyLess
  2. Add the .less NuGet package dotless to your project.添加.less Nuget包dotless到你的项目。
    NuGet dotless install
  3. Add a class that implements the IBundleTransform interface. For the .less transform, add the following code to your project.添加一个实现了IBundleTransfrom接口的类。为了转换.less,添加下列代码到你的项目中。

    using System.Web.Optimization;
    
    public class LessTransform : IBundleTransform
    {
        public void Process(BundleContext context, BundleResponse response)
        {
            response.Content = dotless.Core.Less.Parse(response.Content);
            response.ContentType = "text/css";
        }
    }

     

  4. Create a bundle of LESS files with the LessTransform and the CssMinify transform. Add the following code to the RegisterBundles method in the App_Start\BundleConfig.cs file.使用LessTransform和CssMinify转换去创建一个LESS文件的捆绑包。添加下面的代码到App_Start\BundleConfig.cs文件的RegisterBundles方法

    var lessBundle = new Bundle("~/My/Less").IncludeDirectory("~/My", "*.less");
    lessBundle.Transforms.Add(new LessTransform());
    lessBundle.Transforms.Add(new CssMinify());
    bundles.Add(lessBundle);

     

  5. Add the following code to any views which references the LESS bundle.添加下面的代码到任意调用less捆绑包的视图。

    @Styles.Render("~/My/Less");

     

Bundle Considerations 捆绑注意事项

A good convention to follow when creating bundles is to include "bundle" as a prefix in the bundle name. This will prevent a possible routing conflict.创建捆绑包是使用“bundle”作为前缀是一个应该遵循的很好的约定。这样可以防止可能的路由冲突。

Once you update one file in a bundle, a new token is generated for the bundle query string parameter and the full bundle must be downloaded the next time a client requests a page containing the bundle. In traditional markup where each asset is listed individually, only the changed file would be downloaded. Assets that change frequently may not be good candidates for bundling.一旦你修改了捆绑包中的一个文件,针对捆绑包的查询参数将会生成一个新的token,并且下次客户端请求包含该捆绑包的页面时,整个捆绑包都需要重新下载。在每个资源被单独列出的传统标记中,只有被修改的文件被下载。经常被修改的资源不适合捆绑。

Bundling and minification primarily improve the first page request load time. Once a webpage has been requested, the browser caches the assets (JavaScript, CSS and images) so bundling and minification won't provide any performance boost when requesting the same page, or pages on the same site requesting the same assets. If you don't set the expires header correctly on your assets, and you don't use bundling and minification, the browsers freshness heuristics will mark the assets stale after a few days and the browser will require a validation request for each asset. In this case, bundling and minification provide a performance increase after the first page request. For details, see the blog Using CDNs and Expires to Improve Web Site Performance.捆绑和压缩主要改善页面的首次加载时间。一旦页面是被请求过的,浏览器缓存各种资源(js,css,图片),所以访问同一个页面或者同一个网站的相同资源,绑定和压缩不会起到任何优化的效果。如果你没有给资源设置正确的过期头信息或者没用使用绑定和压缩,浏览器新鲜度试探法将会在几天以后标记资源过期,浏览器将会为每个资源重新发送有效的请求。这种情况下,绑定和压缩在页面第一次请求后提升了性能。关于细节,请查看博客Using CDNs and Expires to Improve Web Site Performance

The browser limitation of six simultaneous connections per each hostname can be mitigated by using a CDN. Because the CDN will have a different hostname than your hosting site, asset requests from the CDN will not count against the six simultaneous connections limit to your hosting environment. A CDN can also provide common package caching and edge caching advantages.使用CDN可以缓解浏览器对于一个主机只能有6个并发的限制,因为CDN的主机名与主站点不同,对CDN的资源请求数不会占用主机的并发。CDN也可以提供通用包缓存和边缘缓存的有点。

Bundles should be partitioned by pages that need them. For example, the default ASP.NET MVC template for an internet application creates a jQuery Validation bundle separate from jQuery. Because the default views created have no input and do not post values, they don't include the validation bundle.捆绑包会被需要他们的页面分割。例如,网站程序的默认Asp.Net MVC模版创建一个从jquery分离的jquery验证包。因为默认创建的视图没有输入,不传递值,所以不包含验证包。

The System.Web.Optimization namespace is implemented in System.Web.Optimization.DLL. It leverages the WebGrease library (WebGrease.dll) for minification capabilities, which in turn uses Antlr3.Runtime.dll.System.Web.Optimization命名空间在System.Web.Optimization.DLL中实现。它利用了WebFrease库的压缩能力,也可以是用Antlr3.Runtime.dll

I use Twitter to make quick posts and share links. My Twitter handle is: @RickAndMSFT

posted on 2017-04-04 15:30  MAQNH  阅读(375)  评论(0编辑  收藏  举报