Javascript '的成本是多少$(这)&"x27"?;?

Javascript '的成本是多少$(这)&"x27"?;?,javascript,jquery,performance,Javascript,Jquery,Performance,这里的人经常建议缓存从DOM元素创建的jQuery对象,如下代码所示: $('#container input').each(function() { $(this).addClass('fooClass'); $(this).attr('data-bar', "bar"); $(this).css('background-color', 'red'); }); 缓存jQuery对象真的提高了代码的性能吗 将DOM元素传递给jQuery构造函数时,“幕后”会发生什么?

这里的人经常建议缓存从
DOM
元素创建的
jQuery
对象,如下代码所示:

$('#container input').each(function() {
    $(this).addClass('fooClass');
    $(this).attr('data-bar', "bar");
    $(this).css('background-color', 'red');
});
  • 缓存jQuery对象真的提高了代码的性能吗
  • 将DOM元素传递给jQuery构造函数时,“幕后”会发生什么?
在jQuery中,出现以下警告:

jQuery函数$()非常昂贵。重复地打电话效率极低

嗯。。。这仅适用于字符串选择器,使用正则表达式对其进行解析以确定它们是什么:

quickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/
是的,它很贵,但这只适用于选择器

如果我们传递一个
domeElement
,jQuery所做的唯一操作就是将domeElement参数保存为新创建的jQuery对象的上下文,并将上下文的长度设置为1:

// Handle $(DOMElement)
if ( selector.nodeType ) {
    this.context = this[0] = selector; // Selector here is a DOMElement
    this.length = 1;
    return this;
}
我确实这样做了,我发现缓存jQuery对象的效果确实很小:


在Chrome中,速度仅慢7%。(在IE中,它更重要一点:12%)

要回答第二个问题,请看:


关于性能差异,如果您希望在两者之间进行直接比较,那么删除任何可能扭曲结果的额外代码(如DOM选择和其他不直接相关的方法)是很有帮助的

在更真实的环境中,测试显示,相对差异很小

另一件需要记住的事情是,每次创建jQuery对象时,都需要为其分配内存,这增加了垃圾收集器需要完成的工作


所以我认为人们建议缓存的原因是出于某种原则性的观点。正在进行的额外工作虽然通常不会产生明显的影响,但最终需要一些可以轻松避免的开销。

此处所有运行时性能测试都忽略的一件事是另一个主要考虑事项:

网络带宽。

$(this)
缓存到局部变量通常会减小脚本的大小,尤其是在缩小脚本时(因为
this
不能从四个字符减少)

考虑:

function hello(text) {
    $(this).attr();
    $(this).css();
    $(this).data();
    $(this).click();
    $(this).mouseover();
    $(this).mouseleave();
    $(this).html(text);
}
hello('Hello world');
闭包编译器的缩小输出是

function hello(a){$(this).attr();$(this).css();$(this).data();$(this).click();$(this).mouseover();$(this).mouseleave();$(this).html(a)}hello("Hello world");
function hello(b){var a=$(this);a.attr();a.css();a.data();a.click();a.mouseover();a.mouseleave();a.html(b)}hello("Hello world");
这节省了39个字节(20%)。现在考虑:

function hello(name) {
    var $this = $(this);
    $this.attr();
    $this.css();
    $this.data();
    $this.click();
    $this.mouseover();
    $this.mouseleave();
    $this.html(name);
}
hello('Hello world');
缩小的输出是

function hello(a){$(this).attr();$(this).css();$(this).data();$(this).click();$(this).mouseover();$(this).mouseleave();$(this).html(a)}hello("Hello world");
function hello(b){var a=$(this);a.attr();a.css();a.data();a.click();a.mouseover();a.mouseleave();a.html(b)}hello("Hello world");
这节省了74字节(37%),几乎是我们节省字节的两倍。显然,在大型脚本中节省的实际成本会更低,但通过缓存,您仍然可以显著减少脚本的大小

实际上,缓存
$(这个)
只有一个好处。您获得的运行时性能增益虽然很小,但可以测量。更重要的是,您可以减少通过线路传输的字节数,并减少直接转换为更多美元的字节数


当你这样看它时,你实际上可以说重复
$(这个)
而不缓存它是一个可量化的美元成本。

这里有一个很好的小应用程序来查看源代码:现在字符串选择器显然会有一个非常不同的图形。感谢SLaks为我指出jQuery源代码。我不知道为什么一开始我自己没有这样做。+1,虽然这更像是一个答案,说明为什么应该缓存
this
而不是
$(this)
,因为你可以使用
this.value获得相同的结果;此标记名为.tagName;这个.className;这个.nodeType;这…
@gdoron,使用原始DOM和jQuery方法之间有很大区别;它们并不总是可以互换的。(
addClass
data
,animation…)除此之外,
var a=$之间的每次调用仍然有3字节的差异(这一点);A.a、 
var a=此$(a) $(a) this
,会比用非缓存的
this
来gzip代码版本会导致更大的文件。它们肯定都会产生比原始文件更小的文件。重要的不是保存的百分比,因为起始点不同,而是需要测量最终的文件字节大小。在这两种情况下,每次都至少保存一个函数调用。比较不正确…性能上存在重大差异。您应该始终缓存,但在这个特定示例中,你甚至不需要这么做。只需利用jQuery链接:
$(this).addClass('fooClass').attr('data-bar','bar').css('background-color','red')此比较比接受答案的比较好得多。