面向.Net程序员的前端优化

背景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引用,而后在RegisterRoutes() 或者 Application_Start()添加方法RouteTable.Routes.AddCombresRoute("Combres")github

  .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仍是部署发布都更合理没有必要再浪费后端的处理资源。


本篇先到此,但愿对你们有帮助!

相关文章
相关标签/搜索