提纲
- 总是从#id继承
- Class前加tag名
- 缓存jQuery对象
- 善于使用jQuery连缀的写法
- 使用子查询
- 尽量减少直接 操作(Manipulation)DOM
- 使用时间委托(别名.冒泡)
- 消除无用的查询
- 延迟加载到 $(window).load
总是从#id继承
jQuery最快的选择器是ID ($(‘#someid’)). 因为直接对应JavaScript方法, getElementById().
看看class是怎么选的 ($(‘sometag.someclass’)).
比如我们要选择单个元素如,选择一个button,我们html代码:
慢的写法:
直接选中按钮更快:
再比如我们要选择多个元素:
多个元素的选择,就是DOM的遍历和循环,这种实现方式比较慢。为了优化性能,应该总是从最近的带ID的父元素继承:
Class前加tag名
jQuery中第二快的是tag选择器 ($(‘head’)).同样,也是对应一个纯粹的JS方法, getElementsByTagName()
例如我们的html代码:
应该在class前都加上tag(最好继承自一个ID):
[Note]: class选择器是jQuery中效率最低的选择器;在IE下他遍历整个DOM. 尽各种可能避免这么写. 绝不能在ID前加tag名。
如下,因为它会先遍历所有的<div> 元素,匹配id为‘content’ :
同样,多个id继承是很冗余的做法:
缓存jQuery对象
养成使用变量保存jQuery对象的习惯,如下:
应该是, 先用局部变量保存对象,再进行其他操作:
Tip: 既然我们使用的是jQuery库,通常使用$作为标志,变量以$开头。 记住, 绝不使用同样的jQuery选择器 超过一次
如果你想再程序的其他地方使用jQuery的结果,或者函数不止一次执行,缓存到一个全局范围的对象中
通过定义一个全局变量,可以在其他函数中调用它:
善于使用jQuery连缀的写法
上面的代码也可以写成这样:
这样做的好处是更少更简洁的代码.
使用子查询
jQuery能在一个集合中继续使用选择器.这样减少了性能开销,因为已经将父元素保存在变量中。
比如html代码如下:
我们可以先查询和缓存父元素,真正使用的是它的两个子元素.
[Tip]: 你可以同时声明多个局部变量,用逗号分隔,节约敲键盘的次数!
尽量减少直接 操作DOM
基于的思想是,需要保存在内存中的到底是什么, 再 更新 DOM. 这不是一个jQuery的最佳实践,但却是最有效的js代码.
直接操作DOM元素十分缓慢. 例如,你需要动态创建列表元素,别这么做:
而应该是,在操作DOM之前,先创建列表元素的字符串:
更快的做法, 在插入前把这些元素封装到单独的父节点中:
如果你按照上面的方法,仍然担心性能问题:
- 试试jQuery的 clone() 方法. 它创建了节点数的拷贝.
- 使用 DOM DocumentFragments(一个轻量文档对象,文档树的一部分,或者是将要被插入到文档树的文档对象。
- 非常适合“剪切粘贴”的操作). creator of jQuery points out,性能比直接操作DOM更好
使用时间委托(别名.冒泡)
除非特别指出,每一个事件(如点击鼠标,悬停等),JavaScript都会沿着DOM树“冒泡“到父元素。
这是很有用的一个特性,当许多元素(或节点)都要调用同一个函数。
不应该将一个事件监听功能绑定到多个节点,这是非常低效的,你可以把它绑定到它们的父元素,这样只要绑定一次,辨别出触发事件的节点就可以啦。
例如,假设我们正在开发一个有许多输入框的表单,并在选中时添加/删除一个class。像这样的绑定是低效的:
应该在父级监听点击事件:
当你发现自己绑定同一个事件监听器的到许多相同的节点,你正在降低代码的性能.
消除无用的查询
如果没有找到任何匹配的元素,虽然jQuery将失败的查询处理地很好,它仍然需要花费时间来寻找他们。
如果整个网站需要一个全局的JavaScript,大部分人会用$(document).ready(function(){ // all my glorious code })
实现。
最有效的办法是使用内联的初始化功能,让模板页面能完全控制JavaScript的执行时间和地点。
例如,在您的“文章“的模板页面,在body前写入下面的代码:
如果您的模板中包含了很多模块,虽然单个页面可能用也可能不用,但是由于某些原因,可以模块后立即初始化函数。
html代码:
全局的js库格式如下:
延迟加载到 $(window).load
大多数页面都可以看到 $(document).ready
如果你发现网页载入时停滞, 可能问题就在$(document).ready
上. 通过 将函数绑定到$(window).load
中,减少CPU使用率。
二者的差别在于:
适用场景:像拖拽 (drag and drop)这些功能,结合了视觉效果(effects)和动画(animation)效果,预先获取隐藏的图像等等.