针对我的answer yesterday关于旋转图片的回复,Jamund告诉我使用.data()
代替.attr()
首先我认为他是对的,然后我考虑了更大的背景 ...使用.data()
代替.attr()
总是更好吗?我查看了其他一些帖子,例如what-is-better-data-or-attr或jquery-data-vs-attrdata
答案对我来说不满意......
所以我继续前进并edited the example通过添加CSS。我认为如果每个图像旋转,在每个图像上创建一个不同的样式可能会有用。我的风格如下:
.rp[data-rotate="0"] {
border:10px solid #FF0000;
}
.rp[data-rotate="90"] {
border:10px solid #00FF00;
}
.rp[data-rotate="180"] {
border:10px solid #0000FF;
}
.rp[data-rotate="270"] {
border:10px solid #00FF00;
}
由于设计和编码经常是分开的,因此在CSS中处理此问题可能是一个很好的功能,而不是将此功能添加到JavaScript中。同样在我的情况下,data-rotate
就像特殊状态,图像当前具有。因此,在我看来,在DOM中表示它是有意义的。
我还认为这可能是使用.attr()
与.data()
保存更好的情况。 以前从未在我读过的其中一篇文章中提到过。
但后来我考虑了性能。哪个功能更快?我建立了自己的测试:
<!DOCTYPE HTML>
<html>
<head>
<title>test</title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script type="text/javascript">
function runfirst(dobj,dname){
console.log("runfirst "+dname);
console.time(dname+"-attr");
for(i=0;i<10000;i++){
dobj.attr("data-test","a"+i);
}
console.timeEnd(dname+"-attr");
console.time(dname+"-data");
for(i=0;i<10000;i++){
dobj.data("data-test","a"+i);
}
console.timeEnd(dname+"-data");
}
function runlast(dobj,dname){
console.log("runlast "+dname);
console.time(dname+"-data");
for(i=0;i<10000;i++){
dobj.data("data-test","a"+i);
}
console.timeEnd(dname+"-data");
console.time(dname+"-attr");
for(i=0;i<10000;i++){
dobj.attr("data-test","a"+i);
}
console.timeEnd(dname+"-attr");
}
$().ready(function() {
runfirst($("#rp4"),"#rp4");
runfirst($("#rp3"),"#rp3");
runlast($("#rp2"),"#rp2");
runlast($("#rp1"),"#rp1");
});
</script>
</head>
<body>
<div id="rp1">Testdiv 1</div>
<div id="rp2" data-test="1">Testdiv 2</div>
<div id="rp3">Testdiv 3</div>
<div id="rp4" data-test="1">Testdiv 4</div>
</body>
</html>
它还应该显示预定义的data-test
是否存在差异。
结果是:
runfirst #rp4
#rp4-attr: 515ms
#rp4-data: 268ms
runfirst #rp3
#rp3-attr: 505ms
#rp3-data: 264ms
runlast #rp2
#rp2-data: 260ms
#rp2-attr: 521ms
runlast #rp1
#rp1-data: 284ms
#rp1-attr: 525ms
因此.attr()
函数总是需要比.data()
函数更多的时间。这是我认为的.data()
的论据。因为表现永远是一个争论!
然后我想在这里发布我的结果并提出一些问题,并且在写作的过程中,我与Stack Overflow向我展示的问题进行了比较(类似标题)
而且确实有一个interesting post about performance
我读了它并运行他们的例子。现在我很困惑! 此测试显示.data()
比.attr()
慢!?!!为什么会这样?
首先我认为这是因为一个不同的jQuery库所以我编辑了它并saved the new one。但结果并没有改变......
所以现在我向你提问:
现在取决于表现:
.attr()
显示.attr()
更好,那么使用.data()
而不是数据,性能会成为您的理由吗?虽然数据旨在用于.data()
? 更新1:
我确实看到没有开销.attr()
要快得多。误解了数据:)但我对第二个问题更感兴趣。 :)
您是否愿意使用数据-HTML5属性而不是数据(如果是) 代表一个国家?虽然在当时不需要它 编码?为什么 - 为什么不呢?
您是否还有其他一些理由可以考虑使用.data()
而不是.data()
?例如互操作性?因为attr
是jquery样式,所有人都可以读取HTML属性...
更新2:
我们从T.J Crowder speed test his answer data
attr
看到的速度比attr
快得多!这再次让我困惑:)但请!表演是一个争论,但不是最高的!所以也请回答我的其他问题!
更新3:
我的测试似乎是假的,因为我在测试时使用了fire-bug! Chrome中的同一文件{{1}}更快,jsperf上的第二次测试也表示{{1}}更快
答案 0 :(得分:15)
这个性能部分的问题尖叫过早优化;见下文。 (以免你得到错误的想法:我经常因为想到同样的过早优化问题而感到内疚。)
但要让性能不受影响(图表下方的其他要点):据我所知,attr
比jQuery 1.7.1中的data
更快:http://jsperf.com/jquery-setting-attr-vs-data这让我感到惊讶。并不是说它很可能很重要。
免费条形图(较长的行=较快的性能):
您是否还有其他一些理由可以使用.attr()而不是.data()?
至少有一对想到:
data
的优点是每次都不必写入元素;你只是第一次写入实际的元素,从那时起jQuery只是更新它在一个单独的对象缓存(通过一个键连接到元素)中维护的JavaScript对象中的值。 (我不确定为什么它比attr
慢;也许是因为间接。)
我不喜欢data
的一点是它不对称:第一次访问元素上的data
时,数据对象将使用data-*
属性来播种元件;但从那以后,两者之间没有联系。
示例(live copy | live source):
var target = $("#target");
display("data('foo'): " + target.data("foo"));
display("data-foo: " + target.attr("data-foo"));
display("Setting data('foo')");
target.data("foo", "updated data('foo')");
display("data('foo'): " + target.data("foo"));
display("data-foo: " + target.attr("data-foo"));
display("Setting data-foo");
target.attr("data-foo", "updated data-foo");
display("data('foo'): " + target.data("foo"));
display("data-foo: " + target.attr("data-foo"));
假设#target
元素以data-foo="bar"
开头,输出为:
data('foo'): bar data-foo: bar Setting data('foo') data('foo'): updated data('foo') data-foo: bar Setting data-foo data('foo'): updated data('foo') data-foo: updated data-foo
这可能令人困惑和惊讶。您必须考虑的方式是data-*
属性仅为默认值。我只是不喜欢他们如何依赖你之前是否打过data
;除非您从不直接写入data-*
属性,否则您无法确定将获得的值data
(标记中的原始值,或之前更新的值)你打电话给data
)。对我来说似乎有点混乱,但如果你自己设定规则(永远不要直接写data-*
属性,只使用data
),你就可以避免混乱。
使用attr
时,只能存储字符串。使用data
时,您可以存储任何JavaScript值或对象引用。
因为表演总是一个论点!
不是在2012年。:-)或者至少,相对于其他论点,它在列表中的位置比以前缺少特定的,可证明的性能问题要低很多。
让我们看一下你的runfirst #rp4
结果:attr
的10k次迭代需要515毫秒; data
的10k次迭代耗时268ms。这是51.5 usec(微秒,百万分之一秒),每个26.8 usec。所以你想知道是否使用data
,如果每次操作可以节省24.7 usec。人类在十分之几秒的时间内感知事物。因此,重要的是,你必须在一个紧密的循环中做大约4000次,以便人类注意到差异。即使在mousemove
处理程序中,这甚至都不值得担心。
如果你进入那种领域(紧密循环中为4,000 /秒),你可能想要避免将信息存储在元素上。
答案 1 :(得分:1)
鉴于.data()
确实比.attr()
on most browsers慢,但速度差异在此问题中并不重要,data()
优于attr()
的一个优势如果数据匹配,数据会自动将data-
属性强制转换为numbers
或boolean
值。
这意味着
<div id="boolean" data-t="true" data-f="false">
将导致布尔运行时值为true
&amp;运行时false
:
console.log($('#boolean').data('t')); // reports true (not a string)
console.log($('#boolean').data('f')); // reports false (not a string)
和
<div id="number" data-n="123.456">
运行此命令时,将导致数字运行时值为123.456
:
console.log($('#number').data('n')); // Reports 123.456 (not a string)
另一方面, attr
仅适用于字符串,但会将值转换为字符串以进行保存。当你获取它时,它不会强制赋值。
attr
和data
之间的选择取决于特定示例所需的功能:
data-
设置从服务器注入页面,我倾向于使用data()
来访问它们,只是因为它是更短的代码。 attr()
来保存值。答案 2 :(得分:0)
您可以使用jQuery.data。它几乎总是最快的。 jQuery尝试在每个浏览器上优化其功能,并最大化兼容性。因此,对于新版本的jQuery,您可以获得此功能的性能。
This 2nd test给了我jQuery.data
作为获胜者。