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" class="on" name="light" value="red" /> red</li> <li><input type="radio" class="off" name="light" value="yellow" /> yellow</li> <li><input type="radio" class="off" name="light" value="green" /> green</li> </ul> <input class="button" 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" class="on" name="light" value="red" /> red</li> <li><input type="radio" class="off" name="light" value="yellow" /> yellow</li> <li><input type="radio" class="off" name="light" value="green" /> green</li> </ul> <input class="button" 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" class="on" name="light" value="red" /> red</li> <li><input type="radio" class="off" name="light" value="yellow" /> yellow</li> <li><input type="radio" class="off" name="light" value="green" /> green</li> </ul> <input class="button" 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
代码
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
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
* 试一下jquery提供的clone()方法。clone()方法创建节点数的拷贝,随后你可以在这个副本中进行操作。
* 使用dom documentfragments. as the creator of jquery points out, 比直接操作dom性能上更好. 先创建你需要的结构(就像我们上面用一个字符串做的一样), 然后使用jquery的 insert or replace methods.
7、事件委托(又名:冒泡事件)
除非特别说明,每一个javascript事件(如click, mouseover 等)在dom结构树上都会冒泡到它的父元素上。如果我们想让很多elements(nodes)调用同一个function这是非常有用的。取而代之的是 你可以只对它们的父级绑定一次,而且可以计算出是哪一个节点触发了事件,而不是绑定一个事件监听器到很多节点上这种效率低下的方式。例如,假如我们要开发 一个包含很多input的大型form,当input被选择的时候我们想绑定一个class name。像这样的帮定是效率低下的:
$('#mylist li).bind('click', function(){ $(this).addclass('clicked'); // do stuff });
反而,我们应该在父级侦听click事件。
$('#mylist).bind('click', function(e){ var target = e.target, // e.target grabs the node that triggered the event. $target = $(target); // wraps the node in a jquery object if (target.nodename === 'li') { $target.addclass('clicked'); // do stuff } });
父节点担当着发报机的工作,可以在触发了事件的目标element上做一些工作。如果你发现自己把一个event listener帮定到很多个element上,那么你这种做法是不正确的。
8、消除查询浪费
虽然jquery对没有找到任何匹配的elements处理的很好,但是它还是需要花费时间去查找的。如果你的站点有一个全局的javascript,你可能会把每个jquery function都放在 $(document).ready(function(){ // all my glorious code })里。 不要这样做。只去放一些页面上适合用到的function。这样做最有效的方式是你的模板可以完全控制任何时候或者地方执行javascript以内联脚 本的方式初始化function。例如,在你的“article”页面模板里,你可能在body标签关闭之前包含以下代码
<script type="text/javascript>mylib.article.init();</script>
