在.data或attr中保存对象状态 - 性能vs CSS? [英] Save object states in .data or attr - Performance vs CSS?

查看:206
本文介绍了在.data或attr中保存对象状态 - 性能vs CSS?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为了回应我关于旋转图片的回答 Jamund告诉我使用 .data()而不是 .attr code>



首先我认为他是对的,但我想到了一个更大的上下文 ...总是更好使用 .data()而不是 .attr()?我查看了一些其他帖子,如 what-is-better-data-or-attr < a>或 jquery-data-vs-attrdata



这些答案对我来说并不令人满意...



所以我继续前进,通过添加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 / javascriptsrc =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);
runlast($(#rp2),#rp2);
runlast($(#rp1),#rp1);
});
< / script>
< / head>
< body>
< div id =rp1> Testdiv 1< / div>
< div id =rp2data-test =1> Testdiv 2< / div>
< div id =rp3> Testdiv 3< / div>
< div id =rp4data-test =1> Testdiv 4< / div>
< / body>
< / html>

它还应显示是否与预定义的数据测试有差异



其中一个结果是:

  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 / code>函数总是比 .data()函数需要更多的时间。这是一个参数 .data()我想。因为性能总是一个参数!



然后我想在这里发布我的结果与一些问题,在写作我的行为比较Stack Overflow显示我类似的标题)



真的,有一个关于性能的有趣的帖子



我读了它并运行他们的例子。而现在我很困惑! 此测试显示 .data() .attr()!为什么会这样?



首先我认为这是因为一个不同的jQuery库,所以我编辑它和保存了新的。但结果并没有改变...



现在我对你的问题:




  • 为什么这两个示例中的效果有些差异?

  • 如果代表状态,您更喜欢使用数据HTML5属性而不是数据虽然在编码的时候不需要它吗?为什么 - 为什么不呢?



现在取决于性能:




  • 如果显示 .attr() / code>是更好?虽然数据用于<​​code> .data()



strong> UPDATE 1:

我发现没有开销 .data()更快。误解数据:)但我对我的第二个问题更感兴趣。 :)


您希望使用数据HTML5属性而不是数据,如果
表示状态?虽然在
编码时不需要它吗?为什么 - 为什么不?


是否还有其他原因可以使用 .attr 而不是 .data()?例如互操作性?因为 .data()是jquery样式和HTML属性可以被所有读取...



UPDATE 2:



我们从 TJ Crowder 速度测试 attr 要快得多,因为 data !这再次让我困惑:)但请!性能是一个论证,但不是最高的!



我的测试似乎是假的,因为测试时使用的
fire-bug ! Chrome中列出的相同文件 attr 更快,并且对 jsperf 也表示 attr 更快

解决方案

问题尖叫的过早优化;见下文。



但是获得性能的时候,你会得到一个错误的想法: (其他点在图下面):据我所见, attr 数据 in jQuery 1.7.1: http://jsperf.com/jquery-setting-attr -vs-data 这让我吃惊。



无偿条形图(较长的线条=更快的性能):



img src =https://i.stack.imgur.com/XZga8.pngalt =jsperf的无偿条形图>


是否还有其他原因可以考虑使用.attr()而不是.data()?


一对夫妇的想法:


  1. data 的优点是它不必每次都写入元素;你只是第一次写入实际的元素,从那时起jQuery只是更新一个JavaScript对象中的值,它维护在一个单独的对象缓存(通过键连接到元素)。 (我不知道为什么它比 attr 慢;也许是因为间接。)


  2. 我不喜欢数据的一件事是它不对称:第一次访问数据在元素上,数据对象用来自元素的 data - * 属性播种;



    示例(直播拷贝 | 直播源):

      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
    设置数据('foo')
    数据('foo'):更新数据('foo')
    data-foo:bar
    设置data-foo
    数据('foo'):更新数据('foo')
    data-foo:更新的data-foo


    $ b b

    这可能令人困惑和惊讶。你必须考虑的方式是 data - * 属性只是默认值。我只是不喜欢他们是如此依赖是否你之前或之前调用数据除非您从未直接写入 data - * 属性,您不能确定什么值 data 将获得(来自标记的原始值,或您稍后在调用数据之前更新的值)。它似乎有点混乱我,但如果你设置自己的规则(从来没有写入 data - * 属性直接,只使用 data


  3. 当您使用 attr ,你只能存储字符串。当您使用 data 时,可以存储任何JavaScript值或对象引用。








因为性能总是一个参数!


不是在2012年:-)或者至少,它相对于其他参数,比以前没有一个具体的,可证明的性能问题的列表低很多。



让我们看看你的 runfirst#rp4 结果:1​​0k次迭代 attr 花了515ms; 10k次数据的迭代耗时268ms。这是51.5 usec(微秒百万分之一一秒),每个26.8 usec。所以你想知道是否使用 data 如果它每次操作可以节省24.7 usec。人类感知的东西在十分之几秒的数量级。所以,重要的是,你必须做这个操作大约4000次在一个紧的循环,一个人注意到差异。这甚至不值得担心,即使在 mousemove 处理程序。



如果你进入种类的领土(4,000 /秒在一个紧的循环),你可能想避免存储在元素上的信息。


In response to my answer yesterday about rotating an Image, Jamund told me to use .data() instead of .attr()

First I thought that he is right, but then I thought about a bigger context... Is it always better to use .data() instead of .attr()? I looked in some other posts like what-is-better-data-or-attr or jquery-data-vs-attrdata

The answers were not satisfactory for me...

So I moved on and edited the example by adding CSS. I thought it might be useful to make a different Style on each image if it rotates. My style was the following:

.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;
}

Because design and coding are often separated, it could be a nice feature to handle this in CSS instead of adding this functionality into JavaScript. Also in my case the data-rotate is like a special state which the image currently has. So in my opinion it make sense to represent it within the DOM.

I also thought this could be a case where it is much better to save with .attr() then with .data(). Never mentioned before in one of the posts I read.

But then i thought about performance. Which function is faster? I built my own test following:

<!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>

It should also show if there is a difference with a predefined data-test or not.

One result was this:

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

So the .attr() function did always need more time than the .data() function. This is an argument for .data() I thought. Because performance is always an argument!

Then I wanted to post my results here with some questions, and in the act of writing I compared with the questions Stack Overflow showed me (similar titles)

And true enough, there was one interesting post about performance

I read it and run their example. And now I am confused! This test showed that .data() is slower then .attr() !?!! Why is that so?

First I thought it is because of a different jQuery library so I edited it and saved the new one. But the result wasn't changing...

So now my questions to you:

  • Why are there some differences in the performance in these two examples?
  • Would you prefer to use data- HTML5 attributes instead of data, if it represents a state? Although it wouldn't be needed at the time of coding? Why - Why not?

Now depending on the performance:

  • Would performance be an argument for you using .attr() instead of data, if it shows that .attr() is better? Although data is meant to be used for .data()?

UPDATE 1:
I did see that without overhead .data() is much faster. Misinterpreted the data :) But I'm more interested in my second question. :)

Would you prefer to use data- HTML5 attributes instead of data, if it represents a state? Although it wouldn't be needed at the time of coding? Why - Why not?

Are there some other reasons you can think of, to use .attr() and not .data()? e.g. interoperability? because .data() is jquery style and HTML Attributes can be read by all...

UPDATE 2:

As we see from T.J Crowder's speed test in his answer attr is much faster then data! which is again confusing me :) But please! Performance is an argument, but not the highest! So give answers to my other questions please too!

UPDATE 3:

My test seems to be false because of the fire-bug I used while testing! The same file in chrome listed attr faster and a second test on jsperf also says attr is faster

解决方案

This performance part of the question screams of premature optimization; see below. (Lest you get the wrong idea: I too am frequently guilty of wondering about the same sort of premature optimization question.)

But getting performance out of the way (other points addressed below the graph): As far as I can see, attr is faster than data in jQuery 1.7.1: http://jsperf.com/jquery-setting-attr-vs-data This surprises me. Not that it's remotely likely to matter.

Gratuitous bar graph (longer lines = faster performance):

Are there some other reasons you can think of, to use .attr() and not .data()?

At least a couple come to mind:

  1. The advantage of data is that it doesn't have to write to the element every time; you only write to the actual element the first time, and from then on jQuery is just updating a value in a JavaScript object it maintains in a separate object cache (connected to the element via a key). (I'm not sure why it's slower than attr; perhaps because of the indirection.)

  2. One thing I dislike about data is that it's not symmetrical: The first time you access data on an element, the data object is seeded with data-* attributes from the element; but from there on out, there is no connection between the two.

    Example (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"));
    

    Assuming the #target element starts out with data-foo="bar", the output is:

    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

    That can be confusing and surprising. The way you have to think about it is that the data-* attributes are default values only. I just don't like how they're so dependent on whether you've called data before or not; unless you never write to the data-* attribute directly, you can't be sure what value data will get (the original from the markup, or a value you updated later before you called data). It seems a bit chaotic to me, but if you set yourself rules (never write to data-* attributes directly and only ever use data, for instance), you can avoid the chaos.

  3. When you use attr, you can only store strings. When you use data, you can store any JavaScript value or object reference.


Because performance is always an argument!

Not in 2012. :-) Or at least, it's a lot lower down the list relative to other arguments than it used to be absent a specific, demonstrable performance problem.

Let's look at your runfirst #rp4 results: 10k iterations of attr took 515ms; 10k iterations of data took 268ms. That's 51.5 usec (microseconds, millionths of a second) each vs. 26.8 usec each. So you're wondering whether to use data if it saves you 24.7 usec per operation. Humans perceive things on the order of tenths of seconds. So for it to matter, you have to do this op roughly 4,000 times in a tight loop for a human to notice the difference. That's just not even close to worth worrying about, even in a mousemove handler.

If you're into that kind of territory (4,000/second in a tight loop), you'll probably want to avoid storing the information on the element at all.

这篇关于在.data或attr中保存对象状态 - 性能vs CSS?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆