使用jQuery时的性能优化方案

来源:互联网 发布:在手机上注册淘宝 编辑:程序博客网 时间:2024/04/26 03:19

文章转自:http://blog.csdn.net/cuew1987/article/details/8868420


一、选择器的优化:

1、从ID选择器来继承或者从ID选择器继承来选择多个元素:

[javascript] view plaincopyprint?
  1. var $t=$("#header");  
  2. var $p=$("#header p");  

2、在class选择器前使用tag标签

jQuery中第二快的选择器就是tag选择器(如$("div"),因为它和直接来自于原生的Javascript方法getElementByTagName()。所以最好总是用tag来修饰class(并且不要忘了就近的ID)

[javascript] view plaincopyprint?
  1. $p=$("#top input.input_txt");  

jQuery中class选择器是最慢的,因为在IE浏览器下它会遍历所有的DOM节点。尽量避免使用class选择器。也不要用tag来修饰ID。下面的例子会遍历所有的div元素来查找id为’content’的那个节点:

[javascript] view plaincopyprint?
  1. var $con=$("div#content");  

用ID来修饰ID也是画蛇添足:

[javascript] view plaincopyprint?
  1. var $con=$("#top #content");  


3、使用子查询

将父对象缓存起来以备将来的使用

[javascript] view plaincopyprint?
  1. var $t=$("#header");  
  2. var $p=$t.find("p");  

4、优化选择器以适用Sizzle的“从右至左”模型
自版本1.3之后,jQuery采用了Sizzle库,与之前的版本在选择器引擎上的表现形式有很大的不同。它用“从右至左”的模型代替了“从左至右”的模型。确保最右的选择器具体些,而左边的选择器选择范围较宽泛些:

[javascript] view plaincopyprint?
  1. var $t=$(".top div.inputAdd");  
  2. 而不要使用  
  3. var $t=$("div.top .inputAdd");  


5. 采用find(),而不使用上下文查找

[javascript] view plaincopyprint?
  1. var divs = $('.testdiv''#pageBody'); // 2353 on Firebug 3.6   
  2. var divs = $('#pageBody').find('.testdiv'); // 2324 on Firebug 3.6 - The best time   
  3. var divs = $('#pageBody .testdiv'); // 2469 on Firebug 3.6  


6、利用强大的链式操作

采用jQuery的链式操作比缓存选择器更有效:

[javascript] view plaincopyprint?
  1. $('li.menu-item')  
  2. .click(function () {alert('test click');})                       
  3. .css('display''block')                        
  4. .css('color''red')                        
  5. .fadeTo(2, 0.7);  


7、编写属于自己的选择器

如果你经常在代码中使用选择器,那么扩展jQuery的$.expr[':']对象吧,编写自己的选择器。


二、DOM操作优化:

1、缓存常用的jQuery对象

[javascript] view plaincopyprint?
  1. var $t=$("#top");  
  2. $t.click(function(){});  


2、进行DOM插入时,循环遍历完之后,再总插入节点

3、检查对象是否存在,如果存在再进行某项操作

4、采用jQuery的内部函数data()来存储状态

在元素上存放数据,返回jQuery对象。

如果jQuery集合指向多个元素,那将在所有元素上设置对应数据。 这个函数不用建立一个新的expando,就能在一个元素上存放任何格式的数据,而不仅仅是字符串。

[javascript] view plaincopyprint?
  1. $("div").data("test", { first: 16, last: "pizza!" });  

5、使用jQuery utility函数

$.isFunction,$.isEmpty(),$.isArray(),$.isNumeric(),$.isWindow(),$.isPlainObject(obj);

[javascript] view plaincopyprint?
  1. $.isNumeric("-10");  // true  
  2. $.isNumeric(16);     // true  
  3. $.isNumeric(0xFF);   // true  
  4. $.isNumeric("0xFF"); // true  
  5. $.isNumeric("8e5");  // true (exponential notation string)  
  6. $.isNumeric(3.1415); // true  
  7. $.isNumeric(+10);    // true  
  8. $.isNumeric(0144);   // true (octal integer literal)  
  9. $.isNumeric("");     // false  
  10. $.isNumeric({});     // false (empty object)  
  11. $.isNumeric(NaN);    // false  
  12. $.isNumeric(null);   // false  
  13. $.isNumeric(true);   // false  
  14. $.isNumeric(Infinity); // false  
  15. $.isNumeric(undefined); // false  

 三、事件性能优化

1、使用Event Delegation

指定的元素(属于被选元素的子元素)添加一个或多个事件处理程序,并规定当这些事件发生时运行的函数。

当你在一个容器中有许多节点,你想对所有的节点都绑定一个事件,delegation很适合这样的应用场景。使用Delegation,我们仅需要在父级绑定事件,然后查看哪个子节点(目标节点)触发了事件。当你有一个很多数据的table的时候,你想对td节点设置事件,这就变得很方便。先获得table,然后为所有的td节点设置delegation事件:

[javascript] view plaincopyprint?
  1. $("table").delegate("td""hover"function(){ $(this).toggleClass("hover"); });  

2、使用ready事件简写,这样可以减少代码量

四、测试jQuery

1、标准化你的jQuery代码

你可以用firebug,你也可以用jQuery 快捷函数

[javascript] view plaincopyprint?
  1. /** 
  2. * Doom Tweaks for Javascript Projects 
  3. * 
  4. * @author Dumitru Glavan 
  5. * @version 1.1 (16-JUL-2011) 
  6. * @requires jQuery 
  7. * @link http://dumitruglavan.com 
  8. * 
  9. * @example: $.l(4,5,6); 
  10. * @example: $.time(); 
  11. * @example: $.lt();$('div')$.lt(); 
  12. * @example: $.bm('$('div')'); - benchmark your code 
  13. * @example: $.mockAjax({mockUrl: '/ajax_mocks'}); - mock your ajax calls 
  14. * 
  15. * Dual licensed under the MIT and GPL licenses: 
  16. *   http://www.opensource.org/licenses/mit-license.php 
  17. *   http://www.gnu.org/licenses/gpl.html 
  18. * 
  19. */  
  20. (function ($) {  
  21.   
  22.     /** 
  23.      * Extend Firebug 
  24.      */  
  25.     if (typeof(console) === 'object') {  
  26.         /** 
  27.          * Shortcut function for console.log() 
  28.          */  
  29.         $.extend($, {  
  30.             l: function () {  
  31.                 for (var i = 0; i < arguments.length; i++) {  
  32.                     console.log(arguments[i]);  
  33.                 }  
  34.             }  
  35.         });  
  36.     }  
  37.   
  38.     /** 
  39.      * Shortcut function for getting timestamp in second (PHP like function time()) 
  40.      * @param numeric divideBy - You can switch back to milliseconds by specifying this as 1 
  41.      */  
  42.     $.extend($, {  
  43.         time: function (divideBy) {  
  44.             return ~~(+ (new Date().getTime() / (typeof divideBy === 'undefined' ? 1000 : divideBy)));  
  45.         }  
  46.     });  
  47.   
  48.     /** 
  49.      * Shortcut function for logging time to the Firebug console 
  50.      * call $.lt() then your code then $.lt() again to get the results 
  51.      */  
  52.     $.extend($, {  
  53.         lt: function () {  
  54.             if (this.ltLastTime == null) {  
  55.                 return this.ltLastTime = new Date().getTime();  
  56.             }  
  57.             var diff = new Date().getTime() - this.ltLastTime;  
  58.             this.ltLastTime = null;  
  59.             $.l(diff);  
  60.             return diff;  
  61.         },  
  62.         ltLastTime: null  
  63.     });  
  64.   
  65.     /** 
  66.      * Shortcut function for benchmarking a block of code to the Firebug console 
  67.      * this function will run your code in a for block to create overflow and push the results into Firebug 
  68.      * 
  69.      * @param string benchmarkCode - the block of code you want to benchmark 
  70.      * @param numeric testTime - the number of FOR cicles 
  71.      */  
  72.     $.extend($, {  
  73.         bm: function (benchmarkCode, testTime) {  
  74.             this.testTime = typeof testTime === 'number' ? testTime : 9999;  
  75.             $.lt();  
  76.             for (var i = 0;i < this.testTime;i++) {  
  77.                 eval(benchmarkCode);  
  78.             }  
  79.             $.lt();  
  80.         }  
  81.     });  
  82.           
  83.     /** 
  84.      * Mock ajax requests with a prefilter 
  85.      * 
  86.      */  
  87.     $.extend($, {  
  88.         mockAjax: function (mockOptions) {  
  89.             mockOptions = $.extend({  
  90.                 mockUrl: '/ajax_mocks'  
  91.             }, mockOptions);  
  92.             $.ajaxPrefilter(function(options, originalOptions, jqXHR) {  
  93.                 if (!options.noMock) {  
  94.                     options.url = mockOptions.mockUrl + '?ajax_url=' + encodeURIComponent(options.url);  
  95.                 }  
  96.             });  
  97.         }  
  98.     });  
  99.       
  100. })(jQuery);  


2、jQuery单元测试

测试JavaSript代码最好的方法就是人来测试。但你可以使用一些自动化的工具如Selenium,Funcunit,QUit,QMock来测试你的代码(尤其是插件)。

五、其他

1、使用CDN引入jQuery文件

2、引入最新版本的jQuery文件

3、需要时使用原始javascript,可以更好提高性能

4、压缩JS文件提高加载速度

0 0