昨天看到有博客园网友发布了一篇关于《使用Combres 库 ASP.NET 网站优化》的文章,觉得是个挺不错的脚本优化的类库,而且目前我的项目公务员考试应战平台也有使用到Js以及css合并压缩优化的技术,想看看能不能借鉴下里面的元素。

一、Combres介绍

这里不多做介绍,可以参看http://www.cnblogs.com/shanyou/archive/2010/04/03/1703597.html的链接。

二、如何使用

1. 在Combres官方源码中我们找到combres.xsd, 它在\Source\Combres\Combres\Resources下面,这个XML Schema配置在VS.NET开发环境中,可以产生智能提示,具体操作:将文件放入C:\Program Files\Microsoft Visual Studio 9.0\Xml\Schemas,并且在VS工具中的工具栏中Xml –> Schemas…中选中该xsd,即可产生智能提示。

2. 创建一个管理css,js的xml配置文件:

代码

<resourceSets url="~/combres.axd" 
               defaultDuration="30" 
               defaultVersion="auto"> 
    <resourceSet name="siteCss" type="css"> 
      <resource path="~/App_Themes/Default/default.css"/> 
    </resourceSet> 
  </resourceSets>

其中defaultDuration为缓存过期天数,具体代码可参考:

cache.SetMaxAge(ResourceSet.DurationInDays);

其中defaultDebugEnabled默认是否调试,默认为false;如果为true时,可以看到default.css不压缩,不返回304的Http Code(304代表客户端有缓冲的文档并发出了一个条件性的请求(一般是提供If-Modified-Since头表示客户只想比指定日期更新的文档)。服务器告诉客户,原来缓冲的文档还可以继续使用)

3. 对debugEnabled="false" ,compressionEnabled="true" (compressionEnabled默认为true)配合来使用

代码

<combres xmlns="urn:combres"> 
  <resourceSets url="~/combres.axd" 
                 defaultDuration="30" 
                 defaultVersion="auto" 
                 defaultDebugEnabled="true"> 
    <resourceSet name="siteCss" type="css" debugEnabled="false" compressionEnabled="true"> 
      <resource path="~/App_Themes/Default/default.css"/> 
      <resource path="~/App_Themes/Default/style.css"/> 
    </resourceSet> 
    <resourceSet name="siteJs" type="js"> 
      <resource path="~/App_Script/jquery-1.3.2.js"/> 
    </resourceSet> 
  </resourceSets> 
</combres> 

如果resourceSets 设置了defaultDebugEnabled="true",那么它的所有resourceSet默认情况都不进行脚本合并和压缩

只有resourceSet显示设置属性debugEnabled="false",方可进行脚本合并和压缩。

4. resource的mode属性(dynamic和static):当引用全名路径时,必须使用dynamic:如<resource path=http://localhost:35229/Web/App_Script/jquery-1.3.2.js mode="dynamic"/>,如果使用static将会报错

具体代码可参考:

var path = resource.Mode == ResourceMode.Dynamic 
                               ? resource.Path.ToAbsoluteUrl() 
                               : resource.Path.ResolveUrl();

可以看出实际上Mode为Dynamic时,可取出绝对路径。

5. 各个配置节点下还包含 defaultCssMinifierRef和defaultJSMinifierRef的脚本缩小器引用,Combres里面具有内置的一些缩小器,比如

MSAjaxJSMinifier(MS Ajax Minifier library (http://aspnet.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=34488))

ClosureJSMinifier(Google Closure Compiler (http://closure-compiler.appspot.com/))

YuiCssMinifier(YUI Compressor library (http://yuicompressor.codeplex.com/))

YuiJSMinifier(YUI Combression library (http://yuicompressor.codeplex.com/))

NullMinifier(不做任何处理,直接返回文本)

缩小器属性默认都为default,让我们看下其中一段代码:

代码

public static class Minifier 
        { 
            private static readonly XElement[] EmptyParamList = new XElement[0];

public static readonly MinifierInfo Off = new MinifierInfo 
                                                    { 
                                                        Name = "off", 
                                                        Type = typeof(NullMinifier), 
                                                        BinderType = Binder.Type, 
                                                        Parameters = EmptyParamList 
                                                    };

public static readonly MinifierInfo JS = new MinifierInfo 
                                                    { 
                                                        Name = "default", 
                                                        Type = typeof(YuiJSMinifier), 
                                                        BinderType = Binder.Type, 
                                                        Parameters = EmptyParamList 
                                                    };

public static readonly MinifierInfo Css = new MinifierInfo 
                                                    { 
                                                        Name = "default", 
                                                        Type = typeof(YuiCssMinifier), 
                                                        BinderType = Binder.Type, 
                                                        Parameters = EmptyParamList 
                                                    }; 
        }

说明默认的时候是采用YuiJSMinifier以及YuiCssMinifier缩小器进行压缩。压缩算法分别采用Yahoo.Yui.Compressor.dll中JavaScriptCompressor和CssCompressor类中的Compress方法。

(另附:Microsoft Ajax缩小器支持2个级别的缩小:常规级,以及超级压扁(hypercrunched)级。开发人员在使用常规级缩小时,Microsoft Ajax缩小器将除去所有不必要的空白,注释,花括号以及分号,在启用超级压扁(hypercrunched)级时,Microsoft Ajax缩小器会通过缩小代码局部变量名称,除去调用不到(unreachable)的代码等方式来全力减小JavaScript文件大小。
Microsoft Ajax缩小器下载包含了下述组件:

ajaxmin.exe——缩小JavaScript文件的命令行工具
ajaxmintask.dll——在Visual Studio项目中缩小JavaScript文件的MSBuild任务
ajaxmin.dll——可用在C# 或 VB.NET 应用中缩小JavaScript文件的组件)

6. 配置节点defaultVersionGenerator,作为版本生成器,浏览页面时,将产生这样的地址如:

/Web/combres.axd/siteCss/-1545244924,“1545244924”就是生成出来的版本,默认设置为“Combres.VersionGenerators.HashCodeVersionGenerator”,还可以设置为“Combres.VersionGenerators.Sha512VersionGenerator”,HashCodeVersionGenerator算法返回的是一个整型数值,实际上也是从GetHashCode()优化出来的数值;Sha512VersionGenerator算法返回的是一个64位的hash值。

HashCodeVersion生成器

Sha512Version生成器

7. localChangeMonitorInterval和remoteChangeMonitorInterval:作为监控是否有刷新资源文件的配置,有个.net提供的类FileSystemWatcher对修改的资源文件去判断是否更新,如果更新过去刷新配置,具体实现没有看明白。

8. Fasterflect(A Fast and Simple Reflection API(http://fasterflect.codeplex.com/)),Combres这里运用了一个快速反射的开源组件,详细请参考原链接。

9. dotless.Core(http://www.dotlesscss.com/)

代码

/**/ .rule1 {font-size: 4px;} /**/ 
/**/ 
.rule2 {font-size: 4px;} 
/**/ 
/* */ 
/* comment */ 
/*

comment

*/ 
body { 
    font-size: 4px; 
}

/** Variables **/ 
@brand_color: #4D926F; 
#header { 
  color: @brand_color; 

h2 { 
  color: @brand_color; 
}

/** Mixins **/ 
.rounded_corners { 
  -moz-border-radius: 8px; 
  -webkit-border-radius: 8px; 
  border-radius: 8px; 

#header { 
  .rounded_corners; 

#footer { 
  .rounded_corners; 
}

/** Operations **/ 
@the-border: 1px; 
@base-color: #111; 
#header { 
  color: @base-color * 3; 
  border-left: @the-border; 
  border-right: @the-border * 2; 

#footer { 
  color: (@base-color + #111) * 1.5; 
}

/** Nested Rules **/ 
#header { 
  color: red; 
  a { 
       font-weight: bold; 
       text-decoration: none; 
    } 
}

这个css样式“模版”实现很有意思,通过这种“非正规”并且“变量取法”的程序员习惯的写法,利用dotless.Core.dll组件进行解码,生成一个真正的css样式。官方代码中的css文件带.css.less后缀的名称,其实也可以定义自己的后缀名称。

10. 我们看到官方代码中有行代码:<cr:Include ID="cr" runat="server" SetName="siteJs" HtmlAttributes="a|b|c|d" />

这里用到了一个用户控件,查看它的输出呈现代码:

代码

protected override void Render(HtmlTextWriter writer) 

    if (string.IsNullOrEmpty(HtmlAttributes)) 
    { 
        writer.Write(WebExtensions.CombresLink(SetName)); 
    } 
    else 
    { 
        var attributes = new Dictionary<string, string>(); 
        var array = HtmlAttributes.Split('|'); 
        for (int i = 0; i < array.Length; i += 2) 
        { 
            attributes[array[i]] = array[i + 1]; 
        } 
        writer.Write(WebExtensions.CombresLink(SetName, attributes)); 
    } 
}

通过转换在页面上可以得到这样的源文件:<script type="text/javascript" src="/combres.axd/siteJs/-1949545824" a="b" c="d"></script>

11. global.asax的路径路由功能:

在Global.asax配置RouteTable.Routes.AddCombresRoute("Combres");并且项目添加引用:System.Web.Routing.dll,修改web.config相关UrlRouting配置节点。

查看相关的代码:

代码

public static void AddCombresRoute(this RouteCollection routes, string name) 
        { 
            var url = Configuration.GetCombresUrl(); 
            var adjustedUrl = url.Substring(2); // Remove the "~/" 
routes.Add(name, new Route(adjustedUrl + "/{name}/{version}", 
                                       
new CombresRouteHandler())); 
        }

这里添加了一个路由映射,通过CombresRouteHandler类进行路由处理,查看该代码:

代码

internal sealed class CombresRouteHandler : IRouteHandler 

    public IHttpHandler GetHttpHandler(RequestContext requestContext) 
    { 
        var name = requestContext.RouteData.Values["name"] as string; 
        var version = requestContext.RouteData.Values["version"] as string; 
        return new CombresHandler(name, version); 
    } 
}

其中CombresHandler将执行ProcessRequest方法:

代码

public void ProcessRequest(HttpContext context) 

    if (context == null) 
        return; 
    var settings = Configuration.GetSettings(); 
    try 
    { 
        new RequestProcessor(context, settings, setName, version).Execute(); 
    } 
    catch (ResourceSetNotFoundException ex) 
    { 
        NotFound(context, ex); 
    } 
    catch (ResourceNotFoundException ex) 
    { 
        NotFound(context, ex); 
    } 
}

最核心的就是黑体的部分,其中setName就是文件配置中资源节点的name名称,version就是节点的版本号,Execute方法具体将调用Workflow.Execute()
public void Execute()
{
    using (new Timer("Processing " + ResourceSet.Name, Log.IsDebugEnabled, Log.Debug))
    {
        Workflow.Execute();
    }
}

Workflow实际是一个接口,它的实现为DefaultProcessingWorkflow以及DebugProcessingWorkflow,其中DefaultProcessingWorkflow对资源路径中的内容进行缓存处理,注意看到Execute()方法,方法作为IProcessingWorkflow的接口方法,具体实现中调用方法processor.WriteFromServerCache(),从WriteFromServerCache方法进行缓存处理。

暂时先分析到这里,很多细节上没有去细看,等有空再写篇比较深入点的文章:)

最后附上我测试时用的源代码:CombresSolution.rar

转载于:https://www.cnblogs.com/liping13599168/archive/2010/04/04/1704154.html

Combres库 学习小结以及部分源码分析相关推荐

  1. golang学习之negroni/gizp源码分析

    在 Go 语言里,Negroni 是一个很地道的 Web 中间件,它是一个具备微型.非嵌入式.鼓励使用原生 net/http 库特征的中间件.利用它地Use功能,我们可以很简单地自定义中间件并使用.其 ...

  2. 了不起的 Webpack HMR 学习指南(含源码分析)

    学习时间:2020.06.14 学习章节:<Webpack HMR 原理解析> 一.HMR 介绍 Hot Module Replacement(以下简称:HMR 模块热替换)是 Webpa ...

  3. Netty学习笔记 - 1 (带源码分析部分)

    2021年12月 北京 xxd 一.Netty是什么 Netty 是由 JBOSS 提供的一个 Java 开源框架,现为 Github 上的独立项目. Netty 是一个异步的.基于事件驱动的网络应用 ...

  4. FFmpeg 源码学习(一):avformat_open_input 源码分析

    一.源码方法参数分析 下面是avformat_open_input的方法及参数: /** * Open an input stream and read the header. The codecs ...

  5. boost学习之boost::lock_guard源码分析

    boost::lock_guard可以说是一种比boost::unique_lock轻量级的lock, 简单一些场景可以用它就行了.源码如下: template<typename Mutex&g ...

  6. STL学习(自学手册+源码分析)之RB -tree

    1.1 RB-tree 1.1.1 RB-tree主体部分 template <class Key, class Value, class KeyOfValue, class Compare,c ...

  7. 《跟二师兄学Nacos吧》第1篇 Nacos客户端服务注册源码分析

    开篇构想 在此之前,已经写了十多篇Nacos的文章,感觉Nacos还值得更深入的学习一下.于是萌生了写一个Nacos源码系列专栏的文章. 写作的目标呢,有两个:第一,能够系统的学习Nacos知识:第二 ...

  8. MyBatis 源码分析系列文章合集

    1.简介 我从七月份开始阅读MyBatis源码,并在随后的40天内陆续更新了7篇文章.起初,我只是打算通过博客的形式进行分享.但在写作的过程中,发现要分析的代码太多,以至于文章篇幅特别大.在这7篇文章 ...

  9. EventBus源码分析

    简介 前面我学习了如何使用EventBus,还有了解了EventBus的特性,那么接下来我们一起来学习EventBus的源码,查看EventBus的源码,看看EventBus给我们带来什么惊喜以及编程 ...

最新文章

  1. 转eclipse如何修改dynamic web module version .
  2. java字符串的替换replace、replaceAll、replaceFirst的区别
  3. (转)从零实现3D图像引擎:(6)向量函数库
  4. 题目1065:输出梯形
  5. mysql有没有实现高可用_MySQL高可用架构:mysql+keepalived实现
  6. PPT优秀模板|7个技巧,让你的设计呈现更加完美
  7. Linux 命令(130)—— userdel 命令
  8. SpringBoot+Vue项目上手
  9. 【独家】阿里云罗庆超:对象存储 OSS 海量数据管理和应用最佳实践
  10. 使用Lockdir软件加密解密文件夹
  11. fdfs-文件上传信息返回详情
  12. matlab中画三瓣花瓣,如何绘制漂亮的“花瓣”韦恩图?
  13. 手机浏览器跳微信小程序
  14. 软件单元测试文档,演示文稿软件应用单元测试题
  15. python 埋点_网站js埋点
  16. Python音频转文字
  17. 高薪程序员面试题精讲系列28之你熟悉哪些设计模式?
  18. 银河麒麟系统安装失败
  19. Eye Diagram眼图测量
  20. Programming Differential Privacy第三章

热门文章

  1. 问题 E: 货币兑换 山东科技大学OJ c 语言
  2. anaconda安装python包_Anaconda:安装或更新 Python 第三方包
  3. list集合下标从几开始_Java基础进阶 集合框架详解
  4. Python多种方式实现”欢迎小红“
  5. 花旗银行文章解释DeFi的好处
  6. 去中心化加密指数协议DeHive即将4月14日启动公募
  7. stable_partition http://www.cplusplus.com/reference/algorithm/stable_partition/
  8. BZOJ 1444 [JSOI2009]有趣的游戏 (Trie图/AC自动机+矩阵求逆)
  9. PyQt5 GUI Programming With Python 3.6 (一)
  10. 饮冰三年-人工智能-Python-16Python基础之迭代器、生成器、装饰器