【发布时间】:2010-08-04 16:28:39
【问题描述】:
我最近需要将一些数据附加到动态创建的LI elements。在我的第一个例子中,我使用.data() 的方式类似于
var _newli = $('<li>foobar</li>');
_newli.data('base', 'ball');
// append _newli to an `ul`
那.. 非常慢。这个逻辑发生在一个可以轻松增长到 500 多个项目的循环中,这需要很长时间!有时它甚至打破了 javascript 的执行时间框架。
于是我改成了$.data()。不知何故,将数据附加到对象上比通过.data() 方法调用快8x。所以现在看起来像
var _newli = $('<li>foobar</li>');
$.data(_newli[0], 'base', 'ball');
// append _newli to an `ul`
这确实/确实更快,但构建所有元素仍然需要 3-4 秒(!)(在我的真实代码中,每个元素大约有 6 次 $.data 调用)。
所以我真的被困住了,我问自己为什么要使用.data() 或$.data()?我可以将我的数据附加到DOM object。所以我做到了
var _newli = $('<li>foobar</li>');
_newli[0].base = 'ball';
// append _newli to an `ul`
瞧,哇令我震惊,这真是太快了!我简直不敢相信它跑得这么好,没有任何劣势。这就是我的问题所在。到目前为止,我在网上没有发现这种技术有任何缺点。有关于您可以使用这种方式创建的循环引用的阅读,但 AFAIK“仅”在 IE 上且仅当您引用 objects 时。
任何想法专家?
更新
感谢优秀的 cmets 和帖子。简短更新@patrick dw:
你是对的,我在使用$.data() 时传递了底层DOM element。它甚至不适用于 jQuery 对象,至少不像预期的那样。
关于使用一个对象并通过$.date() 传递它的想法我有自己的想法,但是我再次对性能差异感到非常震惊,我决定永远忽略.data() 方法。
【问题讨论】:
-
如果有 "每个元素对 $.data 进行 6 次调用",您是否有理由不只进行一次调用,而是为包含您想要的所有属性的值?
$.data(_newli,'myvalues',{'base':'ball','basket':'ball','foot':'ball'}); -
在一次谈话中,约翰说它很慢,并建议做
var data = $('selector').data(); data['foo'] = 'bar'; data['bar'] = 'foo'; etc.,这样你就只有一个访问它。仅供参考。 -
@jAndy - 您应该将 DOM 元素传递给
$.data()。不是jQuery对象。我想知道这是否也会对性能产生影响。$.data(_newli[0], 'base', 'ball'); -
@patrick dw:更新了帖子! @Felix Kling:听起来很合理,你知道我在哪里可以找到 Resig 演讲/论文吗?无论如何我都会试一试,最大的问题是,
DOM property storage是否接近?否则无论如何它都毫无用处。 -
jAndy - 我使用 Webkit 的配置文件工具做了几个配置文件,使用 @Felix 的解决方案与写入 DOM 元素,分配 one 属性。 如果我在测试中不包括初始变量赋值,数据:0.025ms,DOM:0.040ms。如果我确实包含了
data()、var data = $.data(_newli[0])的变量赋值,它会在 data: 0.040ms 到 0.225ms 之间变化。但这是为了分配一个属性。分配几个属性将缩小一些差距(当它存在时)。在 500 个元素上使用$.data(),其最慢的时间约为 22 毫秒。相当快。同样,这只是 Webkit。
标签: javascript jquery html dom