在ASP.NET中捆绑

ASP.NET is a technology stack that has earned a reputation in enhancing productivity. With the release of ASP.NET 4.5, the stack has pushed the envelope by adding automated bundling of web resources, making it easy and flexible to work with.

ASP.NET是一种技术堆栈,在提高生产力方面赢得了声誉。 随着ASP.NET 4.5的发布,该堆栈通过添加自动捆绑Web资源的方式来推动发展,从而使其易于使用和灵活使用。

In this article, I would like to take a look at bundling in ASP.NET. I’ll explore how seamless it is to set up bundling in any ASP.NET project.

在本文中,我想看看ASP.NET中的捆绑。 我将探讨在任何ASP.NET项目中设置捆绑的无缝程度。

With ASP.NET 4.5, the framework has gained a new namespace called System.Web.Optimization. Let’s see how this works.

使用ASP.NET 4.5,框架获得了一个名为System.Web.Optimization的新命名空间。 让我们看看它是如何工作的。

建立 (Setup)

For this tutorial, I am starting out with an empty ASP.NET MVC project. This way, I can focus on what it takes to get automated bundling set up. The same basic steps also apply to WebForms. I will use Razor and C# for this tutorial.

对于本教程,我将从一个空的ASP.NET MVC项目开始。 通过这种方式,我可以集中精力进行自动捆绑设置。 相同的基本步骤也适用于WebForms。 在本教程中,我将使用Razor和C#。

After clicking through prompts for a new project, add these packages in the NuGet Package Manager Console:

在通过提示单击新项目后,请在NuGet软件包管理器控制台中添加以下软件包:

PM> Install-Package Microsoft.AspNet.Mvc
PM> Install-Package jQuery
PM> Install-Package Bootstrap
PM> Install-Package Microsoft.AspNet.Optimization

I would like you to pay attention to the NuGet package called Microsoft.AspNet.Optimization. If you are working off an existing ASP.NET project, this NuGet package makes your job easy. After it gets installed, all you have to do is set up the rest of the plumbing.

我希望您注意名为Microsoft.AspNet.Optimization的NuGet包。 如果您正在处理现有的ASP.NET项目,则此NuGet包使您的工作变得容易。 安装完毕后,您要做的就是设置其余的管道。

With the web optimization framework, you get the tooling to automate managing web resources. You may find the official documentation at MSDN.

使用Web优化框架,您将获得自动管理Web资源的工具。 您可以在MSDN上找到官方文档。

Now, add a folder named App_Start in your main solution if you don’t have it already. We need to get bundling set up by adding this static class.

现在,如果还没有,请在主解决方案中添加一个名为App_Start的文件夹。 我们需要通过添加此静态类来进行捆绑设置。

public class BundleConfig
{
    public static void RegisterBundles(BundleCollection bundles)
    {
    }
}

Routing is set up with any existing project so I will not be including it in this tutorial.

路由是与任何现有项目一起设置的,因此本教程中不会包括它。

To let the ASP.NET framework know about our newly configured bundles, do this in the Global.asax:

要使ASP.NET框架了解我们新配置的捆绑软件,请在Global.asax

public class Global : HttpApplication
{
    protected void Application_Start(object sender, EventArgs e)
    {
        BundleConfig.RegisterBundles(BundleTable.Bundles);
    }
}

ASP.NET is an event-driven framework. If you can imagine, the IIS server sits idle, waiting for events. In this case it would be client browser requests through HTTP. When your application first fires up, ASP.NET calls Application_Start in Global.asax. Inside Application_Start, is where you get to come in and set up the specific bundles you want to use in your application.

ASP.NET是一个事件驱动的框架。 如果可以想象,IIS服务器将处于空闲状态,等待事件。 在这种情况下,它将是通过HTTP的客户端浏览器请求。 当您的应用程序首次启动时,ASP.NET会在Global.asax调用Application_Start 。 在Application_Start ,您可以进入并设置要在应用程序中使用的特定捆绑软件。

At the end, my solution is set up this way:

最后,我的解决方案是这样设置的:

Solution Setup

观看路况 (Watch the traffic)

It is time to add bundles and see how it plays out inside the browser. Add this to BundleConfig which is the static class I specified above:

现在是时候添加捆绑包了,看看它如何在浏览器中播放。 将此添加到我上面指定的静态类BundleConfig中:

public class BundleConfig
{
    public static void RegisterBundles(BundleCollection bundles)
    {
        bundles.Add(new StyleBundle("~/bundle/bootstrap-styles")
            .Include("~/Content/bootstrap.css")
            .Include("~/Content/bootstrap-theme.css")
            .Include("~/Content/Site.css"));
        bundles.Add(new StyleBundle("~/bundle/Home/Index-styles")
            .Include("~/Content/StyleSheet1.css")
            .Include("~/Content/StyleSheet2.css")
            .Include("~/Content/StyleSheet3.css"));

        bundles.Add(new ScriptBundle("~/bundle/bootstrap-scripts")
            .Include("~/Scripts/bootstrap.js")
            .Include("~/Scripts/jquery-{version}.js")
            .Include("~/Scripts/modernizr-{version}.js"));
        bundles.Add(new ScriptBundle("~/bundle/Home/Index-scripts")
            .Include("~/Scripts/JavaScript1.js")
            .Include("~/Scripts/JavaScript2.js")
            .Include("~/Scripts/JavaScript3.js"));
    }
}

Your specific needs will be different. The method above takes in a BundleCollection as a parameter. Notice, this is the BundleTable.Bundles coming from Global.asax. Then, I craft both style and script bundles to suit my specific needs.

您的具体需求将有所不同。 上面的方法将BundleCollection作为参数。 注意,这是来自Global.asaxBundleTable.Bundles 。 然后,我根据自己的特定需求设计样式和脚本包。

I use the {version} wildcard to tell the bundling engine to grab any version of jQuery that happens to be in my solution. In the Release configuration jQuery .min.js gets added to the bundle, but not in Debug. This gives me flexibility in my development environment when working with jQuery. I can swap out different versions of jQuery and my bundling setup will not care. This same wildcard technique applies to any other client-side library.

我使用{version}通配符来告诉绑定引擎获取碰巧在我的解决方案中的任何版本的jQuery。 在发布配置中,将jQuery .min.js添加到捆绑包中,但未在调试中添加。 使用jQuery时,这为我的开发环境提供了灵活性。 我可以换出不同版本的jQuery,而我的捆绑安装程序将不在乎。 相同的通配符技术适用于任何其他客户端库。

Because I get to make up my own bundles, I can tailor resources I need for specific screens.

因为我要自己制作捆绑包,所以我可以为特定屏幕定制所需的资源。

I placed the ~/bundle/bootstrap-styles and ~/bundle/bootstrap-scripts bundles inside the _Layout.cshtml master page. Since it is verbose with a lot of bootstrap plumbing, I’ll omit it from this tutorial.

我将~/bundle/bootstrap-styles~/bundle/bootstrap-scripts捆绑包放在_Layout.cshtml主页中。 由于它很繁琐,而且引导程序管道很多,因此在本教程中将省略它。

Here is what my Index.cshtml Razor page looks like:

这是我的Index.cshtml Razor页面的外观:

@{
    ViewBag.Title = "Index";
}

@Styles.Render("~/bundle/Home/Index-styles")
<h2>Hello World</h2>
<p>
    Be sure to check out glyphs like these:
    <span class="glyphicon glyphicon-plus"></span>.
</p>
@Scripts.Render("~/bundle/Home/Index-scripts")

Easy. Once bundles get defined, I get to put them anywhere I need in my application. I’m following a simple convention of {Controller}/{Action} to define bundles. You may wish to do the same.

简单。 一旦定义了包,就可以将它们放在应用程序中需要的任何位置。 我遵循{Controller}/{Action}的简单约定来定义包。 您可能希望这样做。

If you find that you get Razor page errors because it can’t find Styles.Render or Scripts.Render. Make sure to include this in your Web.config that’s inside the Views folder.

如果发现由于找不到Styles.RenderScripts.Render而出现Razor页面错误。 确保将此包含在Views文件夹内的Web.config中。

<system.web.webPages.razor>
  ...
  <pages pageBaseType="System.Web.Mvc.WebViewPage">
    <namespaces>
      ...
      <add namespace="System.Web.Optimization"/>
    </namespaces>
  </pages>
  </system.web.webPages.razor>
</system.web.webPages.razor>

This tells the Razor engine to include the System.Web.Optimization namespace when rendering dynamic HTML. You may also include any other namespace you need for your specific project. This will save you from having to fully-qualify each Razor extension.

这告诉Razor引擎在呈现动态HTML时包括System.Web.Optimization命名空间。 您还可以包括特定项目所需的任何其他名称空间。 这将使您不必完全合格每个Razor扩展。

With all this, let’s see the network traffic:

有了这些,我们来看一下网络流量:

Unbundled Network Traffic

Red means the browser sits idle. Yellow is the time the browser takes to make a request. Blue is the time it takes to get a response from the server. With most modern browsers, you can do about six requests per domain at a time. If you need more than six, the browser gets to wait. The request at the very top is the dynamic HTML I must get from the server.

红色表示浏览器处于空闲状态。 黄色是浏览器发出请求的时间。 蓝色是从服务器获得响应所花费的时间。 在大多数现代浏览器中,每个域一次可以处理大约六个请求。 如果需要六个以上,浏览器将等待。 最顶层的请求是我必须从服务器获得的动态HTML。

为什么这么重要? (Why does this matter?)

To use an analogy, you can think of your back-end C# programming language as a spaceship. You get speed and time-warping capabilities when you travel. As long as your back-end runs local on your server you can assume high performance. But, when the request pipeline hits HTTP it is a completely different story.

为了进行类比,您可以将您的后端C#编程语言视为一艘太空飞船。 旅行时,您将获得速度和时间扭曲功能。 只要您的后端在服务器上本地运行,就可以实现高性能。 但是,当请求管道到达HTTP时,情况就完全不同了。

I’d like to think of the HTTP network protocol as a mule cart. No matter how much optimization you do on the back-end, you can always rely on the fact that HTTP is slow. So, just like a mule cart, it is good to load it up with plenty of provisions before sending it across town. Round-tripping the server over and over is a sure way to kill performance.

我想将HTTP网络协议视为m子车。 无论您在后端进行了多少优化,您都可以始终依靠HTTP运行缓慢这一事实。 因此,就像a子车一样,在将其运送到整个城镇之前,最好将其装载很多食物。 一遍又一遍地往返服务器是确保性能的肯定方法。

HTTP requests are expensive. Your primary objective is to reduce the number of round trips you do over HTTP.

HTTP请求很昂贵。 您的主要目标是减少通过HTTP执行的往返次数。

启用 (Enabling)

To turn on bundling in the framework, all you need to do is change the Web.config in your solution folder.

要在框架中打开捆绑,您需要做的就是更改解决方案文件夹中的Web.config

<compilation debug="false" targetFramework="4.5" />

You may also hard code it with:

您也可以使用以下代码进行硬编码:

BundleTable.EnableOptimizations = true;

When you hard code it in C#, this takes precedence over the Web.config. In a typical setup you can use a Web.config transformation to enable it in Release mode. There is no need to attempt to debug minified JavaScript code.

当您使用C#对其进行硬编码时,它优先于Web.config 。 在典型的设置中,您可以使用Web.config转换在发布模式下启用它。 无需尝试调试最小JavaScript代码。

Let’s see the bundled traffic:

让我们看看捆绑的流量:

Bundled Network Traffic

Beautiful. Resources start loading as soon as the dynamic HTML gets loaded. Here, I take full advantage of the browser capability since I have exactly six resources. Notice the last resource doesn’t start until all other resources get rendered. This is because it is a web font, and it originates from a CSS bundle.

美丽。 一旦动态HTML被加载,资源便开始加载。 在这里,由于我只有六个资源,因此可以充分利用浏览器的功能。 请注意,直到渲染所有其他资源后,最后一个资源才开始。 这是因为它是一种网络字体,并且源于CSS包。

快取 (Caching)

When bundling gets turned on, an added bonus is resources get cached in the browser for about one year. If your resources change before that, the query string appended to the end will change. This will, in effect, expire any resources the browser no longer needs. This is often referred to as cache busting.

启用捆绑后,额外的好处是资源在浏览器中缓存了大约一年。 如果您的资源在此之前更改,则附加在末尾的查询字符串将更改。 实际上,这将使浏览器不再需要的所有资源失效。 这通常称为缓存清除。

For example, this is what our bundled resources look like:

例如,这是我们捆绑的资源的样子:

/bundle/bootstrap-styles?v=epi1k_G4Tsd0o4dXIOJcBg5gefY7ieCSx0AUDxqm78U1
/bundle/Home/Index-styles?v=uxFDb5XiuKadZOyd2DKyzUU-mh3OUTNuikUDUlL7e_Q1
/bundle/Home/Index-scripts?v=Giv511fvuZRlJKLjJDPqmIxOhmtht9zFlW7lvvTMf0Y1
/bundle/bootstrap-scripts?v=j4YIBwFVDdtvOMWp63GzkWLSoYrcw0ertU_njZLALnk1

The query string appended at the end is a hash from the specific contents of each bundle. When the contents inside the bundle change, the hash appended as a query string will change too.

末尾附加的查询字符串是来自每个捆绑软件特定内容的哈希。 当包中的内容更改时,作为查询字符串附加的哈希也将更改。

You may inspect the HTTP headers.

您可以检查HTTP标头。

Caching HTTP Headers

The Expires HTTP header is set to expire one year into the future.

Expires HTTP标头设置为在一年后到期。

结论 (Conclusion)

ASP.NET is a cool technology designed to make your life easy. What I love the most about this is how the engine renders <link> and <style> tags for you. What I’ve always found most troubling is how these tags end up all over the place. Making it a nightmare to manage web resources.

ASP.NET是一项很酷的技术,旨在使您的生活变得轻松。 我最喜欢的是引擎如何为您呈现<link><style>标签。 我一直最感到困扰的是这些标签在整个地方是如何结束的。 管理Web资源成为一场噩梦。

I hope you can see how seamless it is to add automated bundling into your project. For a simple demo that demonstrates the basic technique, be sure to check out GitHub.

希望您能看到将自动捆绑添加到项目中的无缝性。 对于演示基本技术的简单演示,请务必查看GitHub

How have you found ASP.NET’s bundling features? Do you have any tips for improving performance?

您如何找到ASP.NET的捆绑功能? 您有提高性能的技巧吗?

翻译自: https://www.sitepoint.com/bundling-asp-net/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值