使用jquery编写前端应用有将近4个月的时间了,之前一直专注于系统功能的实现,却忽略了代码的质量和效率。近期对之前写过的代码进行优化和重构,参考了网上一些资料,发现自己之前写的那些代码执行效率很低。遂整理了这篇笔记,希望以此作为今后编码的规范和标准,逐步提高代码质量。
1.在jQuery中最快的选择器是ID选择器,请尽量使用ID代替Class,而且选择器应从最近的ID开始继承。
2.在jQuery中第二快的选择器是tag(标签)选择器( 比如:$("head") ), 如果使用类选择器,建议在class前使用tag(标签名).
3.永远不要让相同的选择器在你的代码里出现多次,尤其是在绑定事件的时候要全面检查。
4.为了区分普通的JavaScript对象和jQuery对象,可以在变量首字母前加上$符号。如:var $active_light = $("#traffic_light input.on");
5.对同一对象的多次不同的操作,应使用jQuery的链式操作加以改善。
6.如果你打算在其他函数中使用jQuery对象,那么你必须把它们缓存到全局环境中。如:window.$my = { head : $("head"), traffic_light : $("#traffic_light"), traffic_button : $("#traffic_button") };
7.尽量减少DOM操作,尤其不要在循环体内操作DOM,而应先构建好DOM对象,然后一次性更新DOM。
8.除非在特殊情况下, 否则每一个js事件(例如:click, mouseover等)都会冒泡到父级节点。代替这种效率很差的多元素事件监听的方法就是,你只需向它们的父节点绑定一次。
比如,我们要为一个拥有很多输入框的表单绑定这样的行为:当输入框被选中时为它添加一个class传统的做法是,直接选中input,然后绑定focus等,如下所示:
$("#entryform input").bind("focus", function(){
$(this).addClass("selected"); }).bind("blur", function(){
$(this).removeClass("selected");
});
假设有100个元素,那么这段代码,你绑定了100个事件。
优化后,更高效的方法如下:
$("#entryform").bind("focus", function(e){
var $cell = $(e.target);
// e.target 捕捉到触发的目标元素
$cell.addClass("selected");
}).bind("blur", function(e){
var $cell = $(e.target); $cell.removeClass("selected"); });
优化后的代码,你只为一个元素绑定了1个事件,自然效率更高。
9.通过将jQuery函数绑定到$(window).load 事件的方法来减少页面载入时的cpu使用率。它会在所有的html(包括<iframe>)被下载完成后执行。
代码如下:
$(window).load(function(){
// 页面完全载入后才初始化的jQuery函数.
});
实际上,延迟加载内容还是SEO优化中的一个重要方法。提升页面加载速度,理顺Spiders搜索的HTML内容,通过在页面(或元素)加载之后使用AJAX请求晚加载其他内容,这样用户就可以马上开始浏览,让Spider看到你想要它们进行索引的内容。
10.给选择器一个上下文,$(expression, context);通过它,能缩小选择器在DOM中搜索的范围,达到节省时间,提高效率。如:$('.myDiv' , $("#listItem"))
11.尽量不要使用.live()方法,遇到新增的DOM元素无法响应绑定事件时,建议把绑定事件重新写一次,这种方式的效率明显高于live()方式,特别是在频繁的DOM操作中。
12.可以用子选择器$("#list > p");的时候,就不应该用后台选择器 $("#list p"); 因为后代选择器获取的是元素内部所有元素。
13.使用data()方法存储状态的效率优于新建临时变量。如下所示:
$("button").click(function(){
if( $("p").data("flag") ){
$("p").text("true");
$("p").data("flag",false);
}else{
$("p").text("false");
$("p").data("flag",true);
}
});
14.用for代替each,因为原生函数总是比辅助组件更快。如果遇到需要遍历对象的情况(如:从远程接收的JSON对象),最好重写JSON对象为一个数组。
15.避免无效查询。只运行在页面里用到的函数. 建议使用行内初始化函数, 这样在模板中就能准确的控制何时何处该执行js.
以下是个人总结的4条,不足之处请读者不吝赐教:
a.能用常量的地方尽量不要再申请变量,通常是指在代码中仅使用一次的值。变量有变量的用途,而不是为了好看。同理适用于函数,如果你的某行代码只需要执行一次,何必用函数调用呢?
b.尽量减少重复调用同一函数,如果一个变量在判断结果之前需要被处理,建议先对这个变量处理,而不要每次在判断的时候都临时处理该变量。在if...else语句,或switch..case语句时要注意,在循环体内更要避免。
c.将要加载的函数按照模块进行分类,进入某一模块时,将频繁使用的数据缓存起来,分清哪些数据是不必每次都向服务端请求的,减小向服务端请求的数量。
d.避免同一模块下频繁加载同一JS文件,将模块内通用函数的JS文件在使用之前加载下来(按需加载),需要时直接调用。