日期:2014-05-16 浏览次数:20418 次
随着现在网页设计越来越多的应用javascript技术,而且浏览器的Javascript引擎运行速度也成为各大浏览器比拼性能的重要指标,各家浏览器厂商皆宣称他们的浏览器速度更快,希望搅动现存的竞争态势。IE8浏览器的Javascript运行速度虽然相对于IE7以及IE6有着很大的提升,但相对于Webkit引擎的浏览器还是有一定的差距,在去年的ZDNET Javascript测试上Chrome浏览器表现突出,一举击败Firefox、Safari和微软的IE浏览器。不过因为IE浏览器相对庞大的使用人群,我们有必要为IE浏览器的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')@*/<!doctype html> <html dir=”ltr” lang=”zh-CN”> <head> <meta charset=”utf-8″/> <title>javascript提速技术 by 司徒正美</title> <script type=”text/javascript”> var date = new Date; for (var i = 0; i < 100000; i++) document; alert(new Date - date); </script> </head> <body> </body> </html>
?
运用提速技术后:
<!doctype html> <html dir=”ltr” lang=”zh-CN”> <head> <meta charset=”utf-8″/> <title>javascript提速技术 by 司徒正美</title> <script type=”text/javascript”> /*@cc_on _d=document;eval(’var document=_d’)@*/ var date = new Date; for (var i = 0; i < 100000; i++) document; alert(new Date - date); </script> </head> <body> !!!!!!!! </body> </html>
?
经测试,用了提速技术后,IE的性能比较
?
没有使用提速技术 | 485 | 1110 | 1219 |
使用提速技术后 | 109 | 609 | 656 |
?
没有使用提速技术 | 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就是其代表之一。