jQuery性能优化常用策略
原文链接 https://ronghuaxueleng.github.io/2015/08/26/jQuery-jQuery%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96%E5%B8%B8%E7%94%A8%E7%AD%96%E7%95%A5/
注:以下为加速网络访问所做的原文缓存,经过重新格式化,可能存在格式方面的问题,或偶有遗漏信息,请以原文为准。
写在前面
如果你不会原生js,只会用jquery,那么你必须懂得jquery如何做性能优化。下面我总结了一些常用的,希望对大家有些帮助。
使用最新的jQuery类库
使用合适的选择器
(1) 使用id来定位DOM元素是最高效的方式,如果不能直接用id找到你需要的元素,可以考虑用find()方法。 (2) 标签选择器的性能也是不错的,它是性能优化的第二选择,因为jQuery将直接调用本地方法document.getElementByTagName()来定位DOM元素。 (3) 对于类选择器,现代浏览器和IE9+ 支持本地方法document.getElementByClassName(),而对于老的浏览器如IE8 以及以前的版本,只能靠使用DOM 搜索方式来实现,这无疑对性能产生较大的影响,所以建议大家有选择性的使用它。 (4) 属性选择器无法直接实现,大多都是使用DOM搜索方式来达到效果,很多现代浏览器支持querySelectorAll()方法,但是不同的浏览器的性能还是不一样的,总的来说,使用这种方式性能并不是非常理想。所以尽量避免使用这种有害性能的方式。 (5) 伪类选择器也同样无法直接实现,jQuery需要搜索每一个元素来定位这个元素,这将是对性能造成较大的消耗,尽量不要使用,如果非用不可,就先用ID 选择器定位父元素,然后再使用该选择器。 注意:尽量使用ID选择器,尽量给选择器指定上下文。
<!--more-->
缓存对象
(1) 推荐使用jQuery的链式方式,这样可以最大程度上发挥缓存变量的优点,有效提高代码运行性能。 (2) 如果一个jQuery对象被多次使用,那么可以把它们缓存到全局环境中。记住,永远不要让相同的选择器在代码里出现多次。
循环时的DOM操作
使用jQuery可以很方便地添加、删除或者修改DOM节点,但是在一些循环,例如for()、while()或者$.each() 中处理节点时得值得注意,因为这样很消耗性能,最好的方式是 先把元素字符串全部创建好 再插入到DOM中去。
数组方式使用jQuery对象
(1) 使用jQuery选择器获取结果是一个jQuery对象。然而jQuery类库回让你感觉你正在使用一个定义了索引和长度的数组。再性能方面,建议使用简单for和while循环来处理,而不是$.each(),这样能使你的代码更快。
$.each(array,function(i){
array[i]=i;
});
//替换为:
var array=new Array();
for(var i=0;i<array.length;i++){
array[i]=i;
}
(2) 检查长度也是一个检查jQuery对象是否存在的方式,下面一段代码通过length属性检查页面中是否存在ID为“content”的元素:
var $content=$('#content'); if($content){ //总是true //Do something } if($content.length){ //拥有元素才返回true //Do something }
事件代理
每一个javascript事件都会冒泡到父级节点。当我们需要给多个元素调用同个函数时这点会很有用。比如,我们要为一个表格绑定这样的行为:点击td后,把背景设置为红色,代码如下:
$('#myTable td').click(function(){ $(this).css('background','red'); });
假定有100个td元素,在使用以上方式的时候,你绑定了100个事件,这将带来很负面的性能影响。更好的方式是:向它们的父级节点绑定一次事件,然后通过 event.target 获取到点击的当前元素,代码如下:
$('#myTable').click(function(e){ var $clicked=$(e.target); // e.target 捕捉到触发的目标元素 $clicked.css('background','red'); });
在改进方式中,你只为一个元素绑定了一个事件。显然,这种方式的属性有优于之前那种,同时在1.7版本中提供了一个新的方式 on(),来帮助你将整个事件监听封装到一个便利方法中,如:
$('#myTable').on('click','td',function(){ $(this).css('background','red'); });
将你的代码转换成jQuery插件
如果你的代码需要反复重用,有一种很优雅的写法就是转变成jQuery插件,格式如下:
(function($){ $.fn.yourPluginName=function(){ // your code goes here return this; } })(jQuery);
使用join()来拼接字符串
也许你之前一直使用“+”来拼接长字符串,现在你可以改改了。虽然它可能会是有点奇怪,但它确实有助于优化性能,尤其是长字符串处理的时候。 首先创建一个数组,然后循环,最后使用join()把数组转化为字符串,代码如下:
var array=[]; for(var i=0;i<=10000;i++){ array[i]='<li>'+i+'</li>'; } $('#list').html(array.join(''));
合理使用HTML5的Data属性
data()方法可以获取 data- 格式的 属性值。规则如下:
<div id='d1' data-role='page' data-last-value='43' data-options='{"name":"John"}'></div>
$('#d1').data('role'); //"page" $('#d1').data('lastvalue'); //43 $('#d1').data('options').name; //"John"
尽量使用原生的JavaScript方法
下面一段代码,它用来判断多选框是否被选中:
var $cr=$('#cr'); //jQuery对象 $cr.on('click',function{ if($cr.is(":checked")){ //jQuery方式判断 alert("感谢你的支持,你可以继续操作"); } });
以上方式可以直接用JavaScript方法来实现:
var $cr=$('#cr'); //jQuery对象 var cr=$cr.get(0); //DOM对象,获取$cr[0] $cr.on('click',function(){ if(cr.checked){ //原生的JavaScript方式判断 alert("感谢你的支持,你可以继续操作"); } });
毋庸置疑,第二种方式效率高于第一种方式,因为它不需要拐弯抹角的去调用许多函数。还有更多类似的操作,把如下代码:
$(this).css('color','red'); //优化成: this.style.color="red"; $('<p></p>'); //优化成: $(document.createElement('p'));