与原生DOM方法相比,为什么jQuery选择器的function如此之慢

我知道这个话题已经被多次辩论过了,但是我正在寻找更加技术性和详细的洞察力来了解真正发生的事情。

我设计了一系列测试来比较jQuery最基本的选择器’#id’和’.class’与各种原生DOM方法的速度。

我希望找出结果是什么的确切原因。

以下是测试: http : //jsperf.com/jqueryspeed

最值得注意的是,getElementById显然是最快的。 为了比较,我添加了jQuery(’#id’)和jQuery.fn.init(’#id’)作为测试,两者之间的区别在于第一个确实实现了一个全新的jQuery对象,而第二个是只运行原型函数,因此更快。 所以,这两者之间的区别是可以理解的。

然而,我不理解的主要区别是getElementById的速度和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=init

正如您所看到的,有大量的validation,正则表达式匹配,跨浏览器技巧等。

重要的是要认识到jquery是一个基于javascript构建的库.Javascript直接在浏览器上执行。因为jquery在浏览器执行之前处理了大量的javascript代码。

我个人更喜欢jquery。我真的不想节省那些纳秒秒.jquery提供的简单程度本身就是现象和艺术品。

jQuery没有什么能像本机javascript一样快速执行,这是有原因的:它很难使您的代码跨浏览器兼容且易于使用。 它从大多数方法调用中构建一个jQuery对象。 在这方面,jQuery将比所需的最小数据路径慢得多,因为它希望提供可随时使用的function。

让我们比较这两个“相似”的调用:

document.getElementById("box") :在低于JavaScript的情况下执行简单查找操作的本机方法。 然后它返回已经加载到内存中的DOM元素。 这是最快的方法之一。

$('#box') :在这里,jQuery将首先解析你要求它做什么。 例如,它将validation它是一个格式良好的选择器,然后尝试识别它是什么类型的选择器。 一旦完成validation,它将尝试获取ID为“box”的元素。 之后,他将创建一个新的jQuery对象,用每个预期的属性填充它,并确保所有浏览器(以及旧的浏览器)都获得相同的结果。 这包括许多后备和合规性测试。 当对象即可使用时,您将获得ID为“box”的元素。 不像getElementById()那么简单。 当目标元素不需要jQueryfunction时,许多人更喜欢使用getElementById('box')而不是$('#box')


更新 – 15/02/17:

随着jQuery> = 2.0不再支持臭名昭着的IE 6/7/8,不再需要一些兼容性测试,使jQuery更轻,更快。 如果您不需要支持旧浏览器,则可以使用jQuery> = 2.0而不是1.x来提高整体性能。

我为jQuery.fn.init(document.getElementById('id'))添加了另一个测试用例,它比大多数其他方法更快,因为它既没有解析字符串也没有创建新的jQuery对象(它比getElementById落后大约50%, jsperf ),当我看到在jQuery.fn.init调用期间执行的jquery代码的源代码时:

 function (selector, context, rootjQuery){ if (selector.nodeType) { this.context = this[0] = selector; this.length = 1; return this; } } 

我只能得出结论,Chrome和Firefox工程师在优化本机DOM操作方面做得非常好。