2012年1月4日

启用gzip,deflate压缩可以减少相应的传输量,MVC可以通过自定义actionfilter实现

 

using System.IO; 
using System.IO.Compression;  
 
public class EnableCompressionAttribute : ActionFilterAttribute 

    const CompressionMode compress = CompressionMode.Compress; 
    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
        HttpRequestBase request = filterContext.HttpContext.Request; 
        HttpResponseBase response = filterContext.HttpContext.Response; string acceptEncoding = request.Headers["Accept-Encoding"]; 
        if (acceptEncoding == null
            return
 
        if (acceptEncoding.ToLower().Contains("gzip")) 
        { 
            response.Filter = new GZipStream(response.Filter, compress); 
            response.AppendHeader("Content-Encoding""gzip"); 
        } 
        else if (acceptEncoding.ToLower().Contains("deflate")) 
        { 
            response.Filter = new DeflateStream(response.Filter, compress); 
            response.AppendHeader("Content-Encoding""deflate"); 
        } 
    } 

 

 

posted @ 2012-01-04 11:41 MoonWalker 阅读(14) 评论(0) 编辑

2011年11月18日


 

 SqlParameter vParam = new SqlParameter("@question_type"typeof(byte));

                vParam.Value = QQuestionType;


SqlParameter vParam = new SqlParameter("@question_type"typeof(byte));
                vParam.Value = int.Parse(QQuestionType);

 

第一段和第二段的区别是类型转换,如果question_type字段在数据库是byte类型的话,推荐使用第二种,类型匹配会提高查询性能,当然第一种情况,SQL 会把参数当作nvarchar类型,也是可以运行,只是时间长很多,我估计这种情况应该是没有用到索引

  

 

posted @ 2011-11-18 17:05 MoonWalker 阅读(10) 评论(0) 编辑

2011年9月2日

随着网页越做越复杂,页面上要用到的 JavaScript 也越来越多,一次性把所有可能会用到的 js 全包含在页面中显然不是一个好主意,于是各种各样动态按需加载 js 的方法逐渐流行起来,LABjs 就是这样一个有趣的项目,目前,包括 twitter 在内的很多网站都是 LABjs 的用户。下面将对 LABjs 1.0.4 版的实现原理做一些分析。

  限于篇幅,关于 LABjs 的使用说明这儿就不写了,需要的话请看它的官方文档

  所谓动态加载 js ,指的是在页面上的某一些 js 执行时,由这些 js 动态加载外部的 js (有时候也包含执行页面上已经定义的一些模块函数)。

  粗略整理,加载外部 js 的方法大致有这么几种:

方法说明
XHR Eval通过 Ajax 方式获取代码,并通过 eval 方式执行代码。
XHR Injection通过 Ajax 方式获取代码,并在页面上创建一个 script 元素,将 Ajax 取得的代码注入。
Script in Iframe通过 iframe 加载 js。
Script DOM Element使用 JavaScript 动态创建 script DOM 元素并设置其 src 属性。
Script Defer/Async严格来说,这一条不算是动态加载外部脚本的方法,但很多动态加载外部脚本的方法里都会用到 sctipt 的 defer 或 async 属性,所以也把它单独列在这儿。这个方法利用 script 的 defer 属性,让脚本“推迟”执行,不阻塞页面加载,或者设置 async 属性,让脚本异步执行。遗憾的是这两个属性不是所有浏览器都支持
document.write Script Tag通过 document.write 把 HTML 标签 script 写入到页面中。
cache trick先使用自定义的 script 的 type 属性(如 <script type="text/cache" ...),甚至使用 Image、Object 等 HTML 对象将 js “预下载”(下载到浏览器缓存里),等真正需要执行对应代码时再将它真正地插入页面中。
Web Worker部分浏览器支持 web worker 功能,可以创建一个 worker 在后台工作,包括加载外部脚本。

  各种方式各有优缺点,比如能否跨域、是否会阻塞其它资源的下载(能否并行下载)、能否管理控制执行顺序、耗费的资源、是否兼容各大浏览器等(部分方法的特性可参考这儿)。事实上,如果仅仅只是想把外部 js 动态加载到页面上的话还是很简单的,但如果可能要同时加载多个 js ,希望它们能尽可能快地下载(并行下载),并且有时候可能希望它们能保证执行顺序,而且要兼容各大主流浏览器,就会有一点复杂了。为了实现这样的目标,LABjs 使用了上面方法中的三种,分别是:Script DOM Element、cache trick、XHR Injection。下面我们先详细看一下这三种加载 js 方式的优缺点。

  Script DOM Element

  这是最常用的方式,它的优点很多:可以跨域、可以加载任何格式的外部 js(不需要对外部 js 进行重构)、不会阻塞其它资源的下载、实现简单。并且,在 Firefox/Opera 下,通过这种方式插入多个 js 脚本,浏览器会并行下载这些 js (同时下载几个取决于浏览器的并行连接数),同时还能保证它们的执行顺序与它们被插入页面的顺序相同。不过,在 IE(以及 Safari/Chrome)下,如果用这种方式同时插入多个 js,这些 js 也会并行下载,但浏览器不能保证这些 js 的执行顺序,哪个先下载完浏览器就会先执行哪个。

  从上面可以看到,Script DOM Element这种方式在 Firefox/Opera 下的表现近乎完美,事实上,在这些浏览器下,Script DOM Element 也是 LABjs 默认使用的方式。

  cache trick

  上面我们看到,Script DOM Element方式可以满足 Firefox/Opera 下的需求了,那么 IE/Safari/Chrome 下怎么办呢?LABjs 中使用了一种 cache trick 的手段,它创建一个 script 标签,并将其 type 设为 "text/cache" ,把它插入页面。这种 trick 似乎是 LABjs 的作者 @getify 首先提出来的。这个 "text/cache" 只是为了语义上有意义,你完全可以把 type 属性设为任何不为 "text/javascript" 的值,比如 "love/oldj" 等。

  根据 LABjs 作者博客上的文章,在 IE/Safari/Chrome 这三个浏览器下,如果一个 script 元素的 type 属性为一个类似 "text/cache" 这样的浏览器不认识的值,浏览器仍然会正常下载这些 js ,并且下载完成后正常触发 onload 事件,但是它们将不会执行这些脚本。于是,通过这样的方式可以先将 script 加载到浏览器缓存中,等对应的 js 需要被执行时,再创建一个新的 script 元素,设置其 type 为正确的值,src 为刚才“预下载”的脚本的值,将其插入页面,这样,这个 script 将会从缓存(而不是网络)瞬间加载对应的 js,并立即执行。通过这样的方式,LABjs 在 IE/Safari/Chrome 等浏览器下实现了脚本的预加载以及执行顺序管理。

  另外,"text/cache" 这种 trick 在 Firefox/Opera 下是不能工作的,因为这两种浏览器会拒绝下载它们不认识的 type 的 script,这样也就无法“预加载”了。不过这不会造成问题,因为这两种浏览器可以直接通过上面的 Script DOM Element 的方式来加载外部脚本。(Firefox 4 曾试图更改相关特性,结果导致 getify 的强烈不满,具体事件可看这里。)同时,这种方法需要浏览器支持并且开启缓存,如果浏览器禁用或不支持缓存,也就无法“预加载”了,而且更糟糕的是,几乎没有 js 方法能检查用户浏览器是否支持并开启了缓存。

  XHR Injection

  cache trick 方式虽然可以实现并行下载、管理执行顺序,但毕竟是一种很依赖于特定浏览器特定版本的特性的方法,如果万一哪一天某个浏览器某个新版本改变了它的特性,这种方式可能就失效了,作者本人也觉得它很丑。所以,如果 LABjs 检测到要下载的外部 js 与当前页面是同域并且浏览器不为 Firefox/Opera(不能保证执行顺序与插入顺序一致)的话,它会优先采用 XHR Injection 的方式。

  XHR Injection 的原理很简单,就不多说了。下面我们来看一看有了这三种方式后, LABjs 是如何实现的。

  LABjs 的内部逻辑比较复杂,变量也比较多。不过简单来看,LABjs 的结构主要如下图所示。

  LABjs

  可以看到,LABjs 对外公开的 API 一共有 4 个方法,分别为 setGlobalDefaults() 方法,setOptions() 方法,script() 方法以及 wait() 方法。其中最常用的是 script() 以及 wait()。LABjs 的内部变量中,最重要的是一个叫 engine 的对象,它负责 script() 以及 wait() 方法的具体实现以及内部变量的维护。

  engine 对象主要有这么几个方法:script()、wait()、loadScript() 以及 waitFunc(),另外还有两个主要的属性:queueExec 及 exec。下面简单解释一下这几个方法及属性的作用。

  script() 公共 API 中的 script() 事实上是生成一个 engine 对象,再调用这个 engine 中的 sctipt() 方法。这个方法根据 queueExec 的值,调用 loadScript() 方法对传入的 js 地址进行加载或预加载操作。

  wait() 公共 API 中的 wait() 事实上是生成一个 engine 对象,再调用这个 engine 中的 wait() 方法。

  loadScript() 加载 js 的方法。根据具体浏览器情况,以及是否同域,这个方法会调用上面提到的三种方式之一来加载 js,或者预加载 js ,或者将预加载完成的 js 最终加载到页面中。

  waitFunc() 每一个 engine 内部有一个 ready 变量,默认为 false,如果这个 engine 要加载的 js 都已加载完成了,则 ready 为 true,同时执行 waitFunc(),这个 waitFunc() 里一般包含你想要在指定 js 加载完成后执行的函数,接下来则是触发下一个 engine(如果有的话)。

  queueExec 这是一个布尔值属性,用于标明当前 engine 加载 js 时是否需要预加载。默认状态下,queueExec为 false,表示直接加载指定的 js,当使用了 wait() 方法后,queueExec 在新生成的 engine 里的值为 true,表示这个 engine 中的 js 先预加载。

  exec 这是一个数组,其中的元素都是待执行的函数。预加载 js 时,loadScript() 会立即执行以便预加载指定 js,同时同样的 loadScript() 也会被 push 一份到当前 engine 对象的 exec 数组中,并在当前 engine 的waitFunc() 执行时被依次调用,loadScript() 这次执行时则会将刚才预加载的 js 真正加载到页面上。

  整个流程大致如下:

  LABjs 流程

  上面这个流程图只是一个简化版(比如有关浏览器判断,以及选择哪种方式下载 js 的部分全部省略了),LABjs 内部的完整的逻辑要更加复杂。

  图中的 ready 表示当前 engine 中引入的 js 是否都已加载完成(LABjs 中有一个同名的内部变量)。可以看到,一开始执行 $LAB.script 时,LABjs 会生成一个 engine 对象,在此之后的链式调用的所有的 script() 方法实际上调用的都是这个 engine 内部的 script() 方法,直到链条上出现 .wait() 为止。wait() 方法将生成一个新的 engine,之后所有通过的 script() 方法引入的 js 都将先被预加载,等上一个 engine 完成时才被触发正式加载。

  关于 LABjs 的实现原理就介绍到这儿了。这篇帖子写了很久,在电脑里及脑子里反复修改了很多次,一直觉得说得不够清楚而不敢放上来,不过貌似现在这个版本依然写得很复杂,要写好技术文章果然不是一件容易的事,呵呵。

  LABjs 中用到了很多技巧,比如用 setTimeout(fn, 0) 的方式把一个耗时的操作“丢”到另一个“线程”上去。如果有兴趣,不妨花一些时间阅读一下它的源代码。与其它动态加载外部 js 的解决方案相比,LABjs 是我见过的最小巧同时最强大的一个,它的最大特点是能尽可能并行地下载待加载的 js ,但需要时又能保证 js 的执行顺序。其它 js loader 也有很多,但它们默认情况下要么不支持并行下载,要么虽然支持并行下载但在部分浏览器下不能保证 js 的执行顺序,从这个角度来看,LABjs 是它们中最出色的。但其它解决方案也各有特色,比如 RequireJS 等,与 LABjs 相比,它不仅能加载外部 js ,还能动态地定义、添加 js 模块,在某些应用场景下,它可能更合适或更为强大。

  另外,LABjs 也有一些不足,比如一些 trick 方法过于信赖特定浏览器特定版本的非标准(或标准中没有定义)的特性,但这些特性是无法通过 js 来检测的,只能通过判断浏览器版本信息以及以往的经验来假设它具有或不具有某种特性。这种方式比较丑陋,而且是不安全的,如果某一天某个浏览器的新版本改变了相关的特性,js 代码将完全无法知道,于是相关的功能或 trick 就失效了。最好的办法是能直接通过检测浏览器特性来完成相关的判断,但谁让有些特性真的难以取到呢?而且,更好的方式,大概是一起推动更合理的标准,让将来某一天在新的浏览器下能非常轻松自然地实现 js loader,让 LABjs 等解决方案彻底地退出前端开发的历史舞台,或许这才是前端工程师们最美好的未来。

  PS. 写完之后,看到这一篇关于预加载资源研究的博客,整理得比较全,值得一读。

原文地址:http://oldj.net/article/labjs-study/ 

posted @ 2011-09-02 11:56 MoonWalker 阅读(20) 评论(0) 编辑

2011年7月29日

 

MVC如果要测试Controller,势必涉及到数据库访问,如果每次都访问同一个数据库必然造成与这个特定的数据库产生了耦合,因此用内存数据库SQLite来测试是最好不过的,同时也利于持续集成,每次测试都产生一个新的数据库,测试完成后废弃掉,以下是配置方式使用FluentNhibernate,需要注意的是构建Sechma的Session需要和数据访问的Session一致才行

 

 

public class NHConfigurator
    {
         
public ISessionFactory _sessionFactory;
         
public static Configuration _configuration;
         
public ISession Session { getset; }

         
public NHConfigurator()
          {
            _sessionFactory 
= CreateSessionFactory();
            Session 
= _sessionFactory.OpenSession();
            BuildSchema(Session);
          }

         
private static void BuildSchema(ISession Session)
         {
             SchemaExport export 
= new SchemaExport(_configuration);
             export.Execute(
truetruefalse, Session.Connection, null);

         }

        
public  ISessionFactory CreateSessionFactory()
        {
            
if(_sessionFactory==null)
            {
                _sessionFactory 
= Fluently.Configure()

                    .Database(
                        SQLiteConfiguration.Standard.InMemory().ShowSql())//生成语句
                    .Mappings(m 
=> m.FluentMappings.AddFromAssemblyOf<your_mapping_class>())
                    .ExposeConfiguration(cfg 
=>_configuration=cfg
                                             )
                    .BuildSessionFactory();
            }
            
return _sessionFactory;
        }
   }

    

 

 

 

 

posted @ 2011-07-29 18:06 MoonWalker 阅读(22) 评论(0) 编辑

2011年6月21日

摘要: Most IDependencyResolver implementations using Unity do not work with IDisposable and using them can lead to memory leaks and connection issues. Unity.Mvc3 is an assembly that includes a fuller implementation of IDependencyResolver that uses a child container per web request to ensure that IDisposab阅读全文
posted @ 2011-06-21 19:21 MoonWalker 阅读(123) 评论(0) 编辑

2011年4月11日

摘要: 这篇文章以非常底层的视角讲述了Web请求(request)在ASP.NET框架中是如何流转的,从Web服务器,通过ISAPI直到请求处理器(handler)和你的代码.看看在幕后都发生了些什么,不要再把ASP.NET看成一个黑盒了.ASP.NET是一个非常强大的构建Web应用的平台,它提供了极大的灵活性和能力以致于可以用它来构建所有类型的Web应用.绝大多数的人只熟悉高层的框架如WebForms和WebServices-这些都在ASP.NET层次结构在最高层.在这篇文章中我将会讨论ASP.NET的底层机制并解释请求(request)是怎么从Web服务器传送到ASP.NET运行时然后如何通过AS阅读全文
posted @ 2011-04-11 12:30 MoonWalker 阅读(27) 评论(0) 编辑

2010年11月5日

摘要: 近期项目需要,做了一段时间的SQL Server性能优化,遇到了一些问题,也积累了一些经验,现总结一下,与君共享。SQL Server性能优化涉及到许多方面,如良好的系统和数据库设计,优质的SQL编写,合适的数据表索引设计,甚至各种硬件因素:网络性能、服务器的性能、 操作系统的性能,甚至网卡、交换机等。这篇文章主要讲到如何改善SQL语句,还将有另一篇讨论如何改善索引。 如何改善SQL语句的一些原...阅读全文
posted @ 2010-11-05 11:23 MoonWalker 阅读(322) 评论(1) 编辑

2010年11月4日

摘要: 使用 Transact-SQL 语句循环结果集有三种方法使用可以通过使用 Transact-SQL 语句遍历一个结果集。 一种方法是使用 temp 表。 使用这种方法您创建的初始的 SELECT 语句的"快照"并将其用作基础"指针"。 例如: 注意 : 两个示例 1 和 2,则假定源表中的每个行唯一的标识符存在。 在某些情况下,可能存在没有唯一标识符。 如果是这种情况,您可以修改 temp 表方法...阅读全文
posted @ 2010-11-04 19:10 MoonWalker 阅读(191) 评论(0) 编辑

2010年9月13日

摘要: 问题 浏览器 DEMO 解决方法 Hacking Rules: property:all-ie\9; property:gte-ie8\0;*property:lte-ie7; +property:ie7; _property:ie6; 1 input[button | submit] 不能用 margin:0 auto; 居中 IE8 bug | fixed 为input添加width 2 bo...阅读全文
posted @ 2010-09-13 13:58 MoonWalker 阅读(86) 评论(1) 编辑

2010年8月12日

摘要: Nicholas C. Zakas大神今年3月协同他Yahoo团队成员出了一本《High Performance Javascript》的书,在这记录读书笔记1.优化javascript加载和执行[代码]  为什么说这样的方式是inefficient?因为每个<script>标签都会阻塞页面的渲染直到js脚本被完全下载然后执行完毕。而页面的渲染是从浏览器解析到<body>标...阅读全文
posted @ 2010-08-12 22:34 MoonWalker 阅读(120) 评论(0) 编辑

公告

昵称:MoonWalker
园龄:2年8个月
粉丝:2
关注:0

导航

<2012年2月>
2930311234
567891011
12131415161718
19202122232425
26272829123
45678910

统计

  • 随笔 - 49
  • 文章 - 0
  • 评论 - 25
  • 引用 - 0

搜索

 
 

常用链接

我的标签

随笔分类

随笔档案

最新评论

阅读排行榜

评论排行榜

推荐排行榜