• 为IE的javascript提速


    我们知道,javascript在执行期时是由内到外执行脚本的,那么离我们的脚本最远的全局对象,很可能要跨越几层作用域才能访问到它。不过在IE中,从最内层到最外层要花的时间比其他多出很多。加之,javascript是一种胶水语言,它必须要调用DOM对能完成我们大多数选择。最著名的就是选择元素(document.getElementById,document.getElementsByTagName,docuemnt.evaluate,document.querySelector),创建元素(document.createElement),此外还有document.body,document.defaultView.getComputedStyle等等,频繁地调用document对象,但是document是位于window对象下,因此这路程就更远了。就了提速,我们必须把它们保存在一个本地变量,那么每次就省得它长途跋涉了。这种技术的运用明显体现在jQuery的源码中:

    (function( window, undefined ) {
    
    // Define a local copy of jQuery
    var jQuery = function( selector, context ) {
    		// The jQuery object is actually just the init constructor 'enhanced'
    		return new jQuery.fn.init( selector, context );
    	},
    
    	// Map over jQuery in case of overwrite
    	_jQuery = window.jQuery,
    
    	// Map over the $ in case of overwrite
    	_$ = window.$,
    
    	// Use the correct document accordingly with window argument (sandbox)
    	document = window.document,
    
            //====================省=================
           }
    // Expose jQuery to the global object
    window.jQuery = window.$ = jQuery;
    
    })(window);
                    

    把window传进闭包内,就省得它每次都往外找window了。

    再看其他类库

    //Raphael 
    window.Raphael = (function () {
        var separator = /[, ]+/,
            elements = /^(circle|rect|path|ellipse|text|image)$/,
            doc = document,
            win = window,
    //************略**************
                    
    //dojo
    d.global = this;
                    
    //Ext
    DOC = document,
                    
    //YUI
    //************略************
                } else if (i == 'win') {
                    c[i] = o[i].contentWindow || o[i];
                    c.doc = c[i].document;
    //************略************
    Y.config = {
    
                win: window || {},
                doc: document,
                    

    但是如果你没有引入类库,如果让IE的javascript跑得更快些呢?用一个变量把它储存起来?在日本博客看到一种很厉害的劫持技术,偷龙转凤把全局变量document变成一个局部变量。

    /*@cc_on _d=document;eval('var document=_d')@*/
                    

    运用提速技术后:

    经测试,用了提速技术后,IE的性能比较

    IE6
    document document.getElementById document.title
    没有使用提速技术4851110 1219
    使用提速技术后109609 656
    IE8
    document document.getElementById document.title
    没有使用提速技术468 797 843
    使用提速技术后78 328 407

    我们看一下实现原理:

    document; 
    doc;      //很明显,调用这个比直接document快,document还要钻进window内部找一番
                    

    如何劫持它呢?

    var doc = document;
    var document = doc;
                    

    这样明显不行因为在预编译阶段,var变量会提前,上面代码相当于

    var doc
    var document  //这里被劫持了
    doc = document //注意,document已经变成undefined
    document = doc //相当于window.undefined = undefined
                    

    没有办法,只好在执行期才定义这个document变量,javascript的动态解析技术派上用场了,eval就是其代表之一。

    var doc = document;
    eval('var document = doc');
                    

    为了让IE专用,用了IE特有的条件编译。

    /*@cc_on 
    var doc = document;
    eval('var document = doc');
    @*/
                    

    嘛,window的东西其实蛮多,我们一一把它们变成本地变量又如何?

    /*@cc_on
    eval((function(props) {
      var code = [];
      for (var i = 0 l = props.length;i<l;i++){
        var prop = props[i];
        window['_'+prop]=window[prop];
        code.push(prop+'=_'+prop)
      }
      return 'var '+code.join(',');
    })('document event body location title self top parent alert setInterval clearInterval setTimeout clearTimeout'.split(' ')));
    @*/
                    

    我们可以再扩展一下,让其更多全局变量或全局方法局部化。不过经验测,FF使用它会报错,chrome则慢了,其他浏览器不明显。

           
            if( !+"\v1"  ){   
              var code = [],ri = 0,prop,str = "var "
              for(var a in window)
                code[ri++] = a;
              for (var i = 0 ,n = code.length;i<n;i++){
                var prop = code[i]
                window['_'+prop] = window[prop];
                str += prop+'=_'+prop+","
              }
              str = str.slice(0,-1);
              eval(str)
            }
                    

  • 相关阅读:
    4
    3
    2
    JAVA中的Token
    swagger2常用注解说明
    Java SimpleDateFormat 中英文时间格式化转换
    Shiro+Redis实现tomcat集群session共享
    理解并设计rest/restful风格接口
    这一篇比上一遍更形象一点,整合到一起看看还是不错的
    SSM 三大框架---事务处理
  • 原文地址:https://www.cnblogs.com/rubylouvre/p/1667628.html
Copyright © 2020-2023  润新知