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构造函数时,“幕后”会发生什么?
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) 如果你正在压缩你的文件,你经常会发现由于这种缓存,文件的大小会稍微大一些。在您的示例中,只有几个字节的差异,111字节与115字节,但它强调了这一点。我不知道为什么会这样,但我经常发现情况就是这样。@user1370958,gzip文件仍然更小,节省的钱更少。在上面的两个例子中,仅通过缩小就可以节省20%和37%;缩小+gzip节省7%和12%。虽然gzip的内容可能比原始内容大,但这通常只发生在非常小的文件(<50字节)上。是的,我的意思是,如果你正在gzip,那么缓存某些东西,比如this
,会比用非缓存的this
来gzip代码版本会导致更大的文件。它们肯定都会产生比原始文件更小的文件。重要的不是保存的百分比,因为起始点不同,而是需要测量最终的文件字节大小。在这两种情况下,每次都至少保存一个函数调用。比较不正确…性能上存在重大差异。您应该始终缓存,但在这个特定示例中,你甚至不需要这么做。只需利用jQuery链接:$(this).addClass('fooClass').attr('data-bar','bar').css('background-color','red')代码>此比较比接受答案的比较好得多。