jQuery性能优化
之前,我们减少字节数和请求次数以及加载顺序以使页面加载的更快。如今,我们越来越多的注意到另一个影响网站性能的部分–cpu利用率。使用 jquery和其他javascript框架,使节点选择和dom操作变得越来越容易,如果使用不当,有可能影响整个网页的响应速度,下面列举11个更有 效的使用jquery库:
1、总是使用#id去寻找element.
在jquery中最快的选择器是id选择器 ($(‘#someid’)). 这是因为它直接映射为javascript的getelementbyid()方法。
选择单个元素
<p id=”content”>
<form method=”post” action=”/”>
<h2>traffic light</h2>
<ul id=”traffic_light”>
<li><input type=”radio” name=”light” value=”red” /> red</li>
<li><input type=”radio” name=”light” value=”yellow” /> yellow</li>
<li><input type=”radio” name=”light” value=”green” /> green</li>
</ul>
<input id=”traffic_button” type=”submit” value=”go” />
</form>
</p>
选择button的性能不好的一种方式:
var traffic_button = $(‘#content .button’);
取而代之的是直接选择button:
var traffic_button = $(‘#traffic_button’);
选择多个元素
在我们讨论选择多个元素的时候,我们真正需要知道的是dom的遍历和循环才是性能低下的原因。为了尽量减少性能损失, 总是使用最近的父id去寻找。
var traffic_lights = $(‘#traffic_light input’);
2、在classes前面使用tags
在jquery中第二快的选择器就是tag选择器 ($(‘head’)). 而这是因为它直接映射到javascript的getelementsbytagname()方法。
<p id=”content”>
<form method=”post” action=”/”>
<h2>traffic light</h2>
<ul id=”traffic_light”>
<li><input type=”radio” name=”light” value=”red” /> red</li>
<li><input type=”radio” name=”light” value=”yellow” /> yellow</li>
<li><input type=”radio” name=”light” value=”green” /> green</li>
</ul>
<input id=”traffic_button” type=”submit” value=”go” />
</form>
</p>
总是在一个class前面加上一个tag名字(记得从一个id传下来)
var active_light = $(‘#traffic_light input.on’);注意:在jquery里class选择器是最慢的一个选择器;在ie中它循环整个dom。可能的话尽量避免使用它。不要在id前面加tags。例如,它会因为去循环所有的<p>元素去寻找id为content的<p>,而导致很慢。
var content = $(‘p#content’);按照同样的思路,从多个id传下来是冗余的。
var traffic_light = $(‘#content #traffic_light’);
3、缓存jquery对象
养成保存jquery对象到一个变量上(就像上面的例子)的习惯。例如,不要这样做:
$(‘#traffic_light input.on).bind(‘click’, function(){…});
$(‘#traffic_light input.on).css(‘border’, ’3px dashed yellow’);
$(‘#traffic_light input.on).css(‘background-color’, ‘orange’);
$(‘#traffic_light input.on).fadein(‘slow’);
取而代之,首现保存jquery变量到一个本地变量后,再继续你的操作。
var $active_light = $(‘#traffic_light input.on’);
$active_light.bind(‘click’, function(){…});
$active_light.css(‘border’, ’3px dashed yellow’);
$active_light.css(‘background-color’, ‘orange’);
$active_light.fadein(‘slow’);
提示:使用$前辍表示我们的本地变量是一个jquery包集。记住,不要在你的应该程序里出现一次以上的jquery重复的选择操作。 额外提示:延迟存储jquery对象结果。
如果你想在你的程序的其它地方使用jquery结果对象(result object(s)),或者你的函数要执行多次,要把它缓存在一个全局范围的对象里。通过定义一个全局容器保存jquery结果对象,就可以在其它的函数里引用它。
// define an object in the global scope (i.e. the window object)
window.$my ={
// initialize all the queries you want to use more than once
head : $(‘head’),
traffic_light : $(‘#traffic_light’),
traffic_button : $(‘#traffic_button’)};
function do_something(){
// now you can reference the stored results and manipulate them
var script = document.createelement(‘script’);
$my.head.append(script);
// when working inside functions, continue to save jquery results
// to your global container.
$my.cool_results = $(‘#some_ul li’);
$my.other_results = $(‘#some_table td’);
// use the global functions as you would a normal jquery result
$my.other_results.css(‘border-color’, ‘red’);
$my.traffic_light.css(‘border-color’, ‘green’);
}
4、更好的利用链
前面的例子也可以这样写:
var $active_light = $(‘#traffic_light input.on’);
$active_light.bind(‘click’, function(){…})
.css(‘border’, ’3px dashed yellow’)
.css(‘background-color’, ‘orange’)
.fadein(‘slow’);
这样可以让我们写更少的代码,使javascript更轻量。
5、使用子查询
jquery允许我们在一个包集上附加其它的选择器。因为我们已经在本地变量里保存了父对象这样会减少以后在选择器上的性能开销。
<p id=”content”>
<form method=”post” action=”/”>
<h2>traffic light</h2>
<ul id=”traffic_light”>
<li><input type=”radio” name=”light” value=”red” /> red</li>
<li><input type=”radio” name=”light” value=”yellow” /> yellow</li>
<li><input type=”radio” name=”light” value=”green” /> green</li>
</ul>
<input id=”traffic_button” type=”submit” value=”go” />
</form>
</p>
例如,我们可以利用子查询缓存active和inactive lights以便后面的操作。
var $traffic_light = $(‘#traffic_light’),
$active_light = $traffic_light.find(‘input.on’),
$inactive_lights = $traffic_light.find(‘input.off’);
提示:可以用逗号隔开一次定义多个本地变量,这样可以节省一些字节。
6、限制直接对dom操作
dom操作的基本做法是在内存中创建dom结构,然后再更新dom结构。这不是jquery最好的做法,但对javascript来讲是高效的。直接操作dom结构性能是低下的。 例如,如果你需要动态创建一列元素,不要这样做:
var top_100_list = [...], // assume this has 100 unique strings
$mylist = $(‘#mylist’); // jquery selects our <ul> element
for (var i=0, l=top_100_list.length; i<l; i++){
$mylist.append(‘<li>’ + top_100_list + ‘</li>’);
}
取而代之,我们希望在插入dom结构之前先在一个字符串里创建一套元素。
代码
var top_100_list = [...], // assume this has 100 unique strings
$mylist = $(‘#mylist’), // jquery selects our <ul> element
top_100_li = “”; // this will store our list items
for (var i=0, l=top_100_list.length; i<l; i++){
top_100_li += ‘<li>’ + top_100_list + ‘</li>’;
}
$mylist.html(top_100_li);
更快的做法,在插入dom结构之前我们应该总是在一个父节点里包含许多元素
var top_100_list = [...], // assume this has 100 unique strings
$mylist = $(‘#mylist’), // jquery selects our <ul> element
top_100_ul = ‘<ul id=”#mylist”>’; // this will store our entire unordered list
for (var i=0, l=top_100_list.length; i<l; i++){
top_100_ul += ‘<li>’ + top_100_list + ‘</li>’;
}
top_100_ul += ‘</ul>’; // close our unordered list
$mylist.replacewith(top_100_ul);
如是你照着上面的做了还是对性能有些迷惑的话,可以参考以下内容:
试一下jquery提供的clone()方法。clone()方法创建节点数的拷贝,随后你可以在这个副本中进行操作。
使用dom documentfragments. as the creator of jquery points out, 比直接操作dom性能上更好. 先创建你需要的结构(就像我们上面用一个字符串做的一样), 然后使用jquery的 insert or replace methods.
7、事件委托(又名:冒泡事件)
除 非特别说明,每一个javascript事件(如click, mouver 等)在dom结构树上都会冒泡到它的父元素上。如果我们想让很多elements(nodes)调用同一个function这是非常有用的。取而代之的是 你可以只对它们的父级绑定一次,而且可以计算出是哪一个节点触发了事件,而不是绑定一个事件监听器到很多节点上这种效率低下的方式。例如,假如我们要开发 一个包含很多input的
下一篇: 好吃又简单的素菜沙拉做法