一、选择器性能优化建议
1,最快的选择器:id选择器和元素标签选择器(尽量使用id代替Class)
这是jQuery选择器的一条黄金法则。jQuery选择一个元素最快的方法就是用ID来选择了。
2,使用匈牙利命名法
在变量前加 $ 前缀,便于识别出 jQuery 对象。
// 糟糕 var first=$('#first'); var second=$('#second'); var value=$first.val(); // 建议 - 在 jQuery 对象前加 $ 前缀 var $first = $('#first'); var $second = $('#second'), var value = $first.val();
3,利用强大的链式操作
采用jQuery的链式操作比缓存选择器更有效:
$('li.menu-item').on("click", function () { alert('test click'); }).css('display', 'block').css('color', 'red').fadeTo(2, 0.7);
二、优化DOM操作建议
4,缓存jQuery对象
将你经常用的元素缓存起来:
1):
var header = $('#header'); var divs = header.find('div'); var forms = header.find('form');
2):
var header = $('#header'); var menu = header.find('.menu'); // 或者 var menu = $('.menu', header);
5,当要进行DOM插入时,尽可能减少写入HTML结构的次数, 多在变量内存里捯饬完了再操作dom。
var menu = ''; for (let i = 1; i < 100; i++) { menu += '' + i + ''; } menu += ''; $('#header').prepend(menu); // 千万不要这样做: $('#header').prepend(''); for (var i = 1; i < 100; i++) { $('#menu').append('' + i + ''); }
(1)改动DOM结构开销很大,因此不要频繁使用.append()、.insertBefore()和.insetAfter()这样的方法。
如果要插入多个元素,就先把它们合并,然后再一次性插入。根据测试,合并插入比不合并插入,快了将近10倍。
(2)如果你要对一个DOM元素进行大量处理,应该先用.detach()方法,把这个元素从DOM中取出来,处理完毕以后,再重新插回文档。根据测试,使用.detach()方法比不使用时,快了60%。
(3)如果你要在DOM元素上储存数据,不要写成下面这样:
var elem = $(‘#elem');elem.data(key,value);
而要写成:
var elem = $(‘#elem');$.data(elem,key,value);
根据测试,后一种写法要比前一种写法,快了将近10倍。因为elem.data()方法是定义在jQuery函数的prototype对象上面的,而$.data()方法是定义jQuery函数上面的,调用的时候不从复杂的jQuery对象上调用,所以速度快得多。
6,使用直接函数,而不要使用与与之等同的函数
为了获得更好的性能,你应该使用直接函数如$.ajax(),而不要使用$.get(),$.getJSON(),$.post(),因为后面的几个将会调用$.ajax()。
7,采用jQuery的内部函数data()来存储状态
不要忘了采用.data()函数来存储信息:
// $('#head').data('name', 'value'); // 辣鸡方法 $.data("#head", 'name', 'value'); // 之后在你的应用中调用: $('#head').data('name');
三、关于优化事件性能的建议
8,推迟到$(window).load
有时候采用$(window).load()比$(document).ready()更快,因为后者不等所有的DOM元素都下载完之前执行。你应该在使用它之前测试它。
9,使用Event Delegation
当你在一个容器中有许多节点,你想对所有的节点都绑定一个事件,delegation很适合这样的应用场景。使用Delegation,我们仅需要在父级绑定事件,然后查看哪个子节点(目标节点)触发了事件。当你有一个很多数据的table的时候,你想对td节点设置事件,这就变得很方便。先获得table,然后为所有的td节点设置delegation事件:
$("table").delegate("td", "hover", function(){ $(this).toggleClass("hover");});
10, 使用ready事件的简写
如果你想压缩js插件,节约每一个字节,你应该避免使用$(document).onready()
// 也不要使用 $(document).ready(function (){ // 代码 }); // 你可以如此简写: $(function (){ // 代码 });
四、测试jQuery
11,jQuery单元测试
测试JavaSript代码最好的方法就是人来测试。但你可以使用一些自动化的工具如Selenium,Funcunit,QUit,QMock来测试你的代码(尤其是插件)。
五、其他常用jQuery性能优化建议
12,使用1.9.1版本的jQuery
这个版本库产生的流量最小, 也实现了常用的功能了。其他版本的jq, 2.2.4也不错。至于高版本的,还不如用vue了。
13,使用HMTL5 和css3
新的HTML5标准带来的是更轻巧的DOM结构。更轻巧的结构意味着使用jQuery需要更少的遍历,以及更优良的载入性能。所以如果可能的话请使用HTML5。
css3在不需要兼容低版本浏览器的时候可以考虑其来代替一些动态效果是一个不错的选择。
14, 从cdn分布式节点载入jQuery框架库
这个需要先从cdn网络优化方面说起, 即便用户不是每次都从服务器拉文件, 那也没人希望用自己的服务器是反复给新用户传输静态文件用的, 一般像jq这种库, 都挂到cdn上。这里需要注意的是,虽然网上有大量的文章要求大伙使用第三方现成的cdn, 经过笔者测试, 不少cdn夹带广告, 搞的网站莫名其妙弹出广告来。所以还是自己去买cdn服务比较好。
16,压缩JavaScript
压缩和最小化你的JavaScript文件。
在线压缩地址: 传送门链接
压缩之前,请保证你的代码的规范性,否则可能失败,导致Js错误。
17,注意定义jQuery变量的时候添加var关键字
这个不仅仅是jQuery,所有javascript开发过程中,都需要注意,请一定不要定义成如下:
$loading = $('#loading'); //这个是全局定义,不知道哪里位置倒霉引用了相同的变量名,就会郁闷至死的
18,多用逻辑判断||或者&&来提速
请勿如下书写:
if(!$something) { $something = $('#something '); }
这样书写性能更好:
$something = $something || $('#something');
19、尽量使用更少的代码
与其这样书写:if(string.length > 0){..}
不如这样书写:if(string.length){..}
20、尽量使用.on方法
如果你使用比较新版本的jQuery类库的话,请使用.on,其它任何方法都是最终使用.on来实现的。
// 糟糕 $first.click(function(){ $first.css('border','1px solid red'); $first.css('color','blue'); }); $first.hover(function(){ $first.css('border','1px solid red'); }) // 建议 $first.on('click',function(){ $first.css('border','1px solid red'); $first.css('color','blue'); }) $first.on('hover',function(){ $first.css('border','1px solid red'); })
21, 尽量使用原生的Javascript
如果使用原生的Javascript也可以实现jQuery提供的功能的话,推荐使用原生的javascript来实现。
22, 正确处理循环
循环总是一种比较耗时的操作,如果可以使用复杂的选择器直接选中元素,就不要使用循环,去一个个辨认元素。
请不要这样用
$('.data').each(function(){ console.log($(this)); });
请考虑这样用
var data = $('.data'); for(i=0;i<data.length;i++){ console.log(data[i]); }
23,避免show()和hide()的使用
当页面上的元素不是很多时,用show和hide看不出什么问题,元素一多,就不行了
我们可以修改css,这样会更快
请不要这样用
$('#temp1').show();$('#temp2').hide();
请考虑这样用
$('#temp1').css('display','block');$('#temp2').css('display','none');
24,事件的委托处理(Event Delegation)(强调第9条)
$('td').bind('click', function(){ // 通过使用滑动效果,在显示和隐藏状态之间切换元素 $(this).toggleClass('click');//进行 slideUp() 和 slideDown() 之间的切换: });
具体的写法有两种。第一种是采用.delegate()方法:
$('table').delegate('td', 'click', function(){ $(this).toggleClass('click'); });
第二种是采用.live()方法:慎用 .live()方法(应该说尽量不要使用)
$('table').each(function(){ $('td', this).live('click', function(){ $(this).toggleClass('click'); }); });
这两种写法基本等价。唯一的区别在于,.delegate()是当事件冒泡到指定的父元素时触发,.live()则是当事件冒泡到文档的根元素后触发,因此.delegate()比.live()稍快一点。此外,这两种方法相比传统的.bind()方法还有一个好处,那就是对动态插入的元素也有效,.bind()只对已经存在的DOM元素有效,对动态插入的元素无效。
25,给选择器一个上下文
jQuery选择器中有一个这样的选择器,它能指定上下文。
jQuery( expression, context ); 通过它,能缩小选择器在DOM中搜索的范围,达到节省时间,提高效率。
普通方式:
以下是引用片段:
$('.myDiv')
改进方式:
以下是引用片段:
$('.myDiv' , $("#listItem") )
注意不是:
var content = $('div #content'); // 非常慢,不要使用
26, 熟记技巧
你可能对使用 jQuery 中的方法缺少经验,一定要查看的文档,可能会有一个更好或更快的方法来使用它。
// 糟糕 $('#id').data(key, value); // 这种方法更搞笑 $.data('#id', key, value);
27,维持代码的可读性
伴随着精简代码和使用链式的同时,可能带来代码的难以阅读。添加缩紧和换行能起到很好的效果。
在实际开发过程中要保证代码的可读性,但是在发布到网上应用环境的时候压缩下,就是同样的代码两个版本:开发版本和应用版本。