为什么jQuery选择器函数与原生DOM方法相比如此缓慢
Why is jQuery selector function so slow compared to native DOM methods
我知道这个话题已经讨论了好几次了,但我正在寻找更技术和详细的见解来了解真正发生了什么。
我设计了一系列测试来比较jQuery最基本的选择器"#id"answers".class"与各种本地DOM方法的速度。
我希望弄清楚为什么结果会是这样。
以下是测试:http://jsperf.com/jqueryspeed
最值得注意的是,getElementById显然是最快的。为了进行比较,我添加了jQuery('#id')和jQuery.fn.init('#id')作为测试,两者之间的区别在于,第一个确实安装了一个全新的jQuery对象,而第二个只运行原型函数,因此速度更快。所以,这两者之间的区别是可以理解的。
然而,我不理解的主要区别是getElementById的速度和jQuery.fn.init的速度之间的巨大差距,jQuery.fn.init有一个简单的测试来以特定的方式处理简单("#id")请求,然后返回到对getElementById本身的调用。
那么,为什么在Chrome上,这种方法比原生方法慢8倍,尽管它基本上只是它的包装器呢?
它也比包装的getElementById$(document.getElementById('#id'))慢3-4倍…
有什么想法吗?
这是当我们使用简单的$('selector')时,jquery所经过的代码量
http://james.padolsey.com/jquery/#v=1.10.2&fn=初始化
正如你所看到的,有很多验证,正则表达式匹配,跨浏览器技巧等。
重要的是要认识到jquery是一个基于javascript构建的库。Javascript直接在浏览器上执行。Where as jquery在被浏览器执行之前处理了相当多的javascript代码。
我个人更喜欢jquery。我真的不在乎节省那些纳米秒。jquery提供的简单程度是惊人的,它本身就是一件艺术品。
jQuery没有什么能比原生javascript做得更快,这是有原因的:它努力使代码跨浏览器兼容且易于使用。它从大多数方法调用中构建了一个jQuery对象。在这种情况下,jQuery将比所需的最小数据路径慢得多,因为它希望提供可供使用的功能。
让我们比较一下这两个"相似"的调用:
document.getElementById("box")
:本机方法,在比JavaScript更低的级别上执行简单的查找操作。然后,它返回已经加载在内存中的DOM元素。这是最快的方法之一。
$('#box')
:在这里,jQuery将从分析您要求它做什么开始。例如,它将验证它是一个格式良好的选择器,然后尝试识别它是什么类型的选择器。一旦完成验证,它将尝试获取ID为"box"的元素。然后,他将创建一个新的jQuery对象,用每个期望的属性填充它,并确保所有浏览器(以及旧的浏览器)都得到相同的结果。这包括大量的回退和合规性测试。当对象准备好使用时,您将获得ID为"box"的元素。没有getElementById()
那么简单。当目标元素不需要jQuery功能时,许多人更喜欢使用getElementById('box')
而不是$('#box')
。
更新-2017年2月15日:
由于jQuery>=2.0不再支持臭名昭著的IE 6/7/8,因此不再需要一些兼容性测试,使jQuery变得更轻、更快。如果不需要支持较旧的浏览器,使用jQuery>=2.0而不是1.x可以提高整体性能。
我为jQuery.fn.init(document.getElementById('id'))
添加了另一个测试用例,它比大多数其他方法都快,因为它既不解析字符串,也不创建新的jQuery对象(它大约落后于getElementById、jsperf的50%),当我看到在jQuery.fn.init
调用期间执行的jQuery代码源时:
function (selector, context, rootjQuery){
if (selector.nodeType) {
this.context = this[0] = selector;
this.length = 1;
return this;
}
}
我只能得出结论,Chrome和Firefox的工程师在优化原生DOM操作方面做得很好。
- electronic BrowserWindow的最小高度和宽度在hide()show()方法之后不起作用
- 有没有任何方法可以将控制器从文件加载到ui路由器$stateProvider中
- 数组在递归方法中设置为null
- 打破承诺链的好方法是什么
- 在使用Polymer'加载所有json文件后执行方法;s的核心ajax
- 使用“;这个“;JavaScript原型方法中的关键字
- 序列化数据属性中对象的最可靠方法
- 对iPad上的点击事件反应缓慢
- 使用Objective-C的JavaScript注入方法
- 有没有一种方法可以添加相同的项目val=“0”;4〃;到JavaScript中数组的每个对象
- 有没有一种方法可以防止img get请求使用css或js发生
- Javascript,有没有一种方法可以将数组写成没有逗号或空格的单个文本字符串
- toBoolean方法类似于toString
- 如何在单击复选框后调用控制器方法
- 是否有任何方法可以使用jQuery替换在数组中定义值的文本
- 递归使用 eval() 是检查程序执行的好方法吗?
- 如何在webView,Android中从@JavascriptInterface方法调用Javascript
- 滚动事件运行缓慢-有没有更轻松的方法
- 为什么jQuery选择器函数与原生DOM方法相比如此缓慢
- focus()或select()方法javascript,在Chrome中性能缓慢