就性能而言,在DOM树中存储20个元素(及其子元素)或存储在Javascript对象中的所有元素是否更好?
案例1:
<html>
<body>
<div id='el1'>
<span>...</span>
...
</div>
<div id='el2'>
<p>...</p>
...
</div>
<div id='el3'>
<img src="" alt="" />
<br/>
</div>
<div id='el4'>
<section></section>
...
</div>
...
</body>
</html>
案例2:
var OBJ = {};
OBJ.el1 = $("<div id='el1'><span>...</span>...</div>");
OBJ.el2 = $("<div id='el1'><p>...</p>...</div>");
OBJ.el3 = $("<div id='el1'><img src="" alt="" /><br/>...</div>");
OBJ.el4 = $("<div id='el1'><section></section>...</div>");
....
我的应用程序应该只显示其中一个元素。如果我将它们留在DOM树中并改变它们的样式,它会表现得更好吗?或者它最好是将它们存储在Javascript对象中并在需要时删除并附加它们?
我该如何测试?
@edit 需要考虑的额外信息:
1-所有元素都写在HTML文档中,然后在加载页面时删除并存储在javascript对象中。
2-每次活动元素发生变化时,我都会通过删除当前活动元素然后将新元素附加到其中来更改DOM结构。
@EDIT 2:经过一些测试后
这个想法是:有人会将HTML元素写入DOM,然后Javascript必须同时显示/隐藏其中一个元素。这些元素都有自己的孩子。它可能是整页网站或Web应用程序。
我创建了2个测试用例:
1-元素将被删除,然后通过Javascript重新添加几次。因此,它们将被存储放在Javascript对象中,直到它被召唤
2- Elements将在DOM中,我将隐藏并显示它们(jQuery函数,但进一步的测试将直接更改CSS)。
<html>
<head>
<script src='https://code.jquery.com/jquery-1.11.3.min.js'></script>
</head>
<body>
<!-- I USED 15 ELEMENTS IN MY TEST, BUT THE CODE IS TOO LONG -->
<script>
var OBJ1 = {};
var OBJ2 = new Array();
var ACTIVE;
var BODY = $(document.body);
var T1, T2, DELTA;
$(function(){
T1 = new Date().getTime();
/*
//TEST 1: Javascript
var _this,id;
$('div').each(function(){
_this = $(this);
id = _this.attr('id');
OBJ1[id] = _this;
_this.remove();
});
var c;
for (var i = 0; i < 10000; i++) {
for(var k in OBJ1){
c = OBJ1[k];
if(ACTIVE) ACTIVE.remove();
BODY.append(c);
ACTIVE = c;
}
}*/
//TEST 2: DOM
var _this,id;
$('div').each(function(){
_this = $(this);
id = _this.attr('id');
OBJ2.push(id);
});
var c;
for (var i = 0; i < 10000; i++) {
for(var k=0,l=OBJ2.length;k<l;k++){
c = $('#'+OBJ2[k]);
if(ACTIVE) ACTIVE.hide();
c.show();
ACTIVE = c;
}
}
T2 = new Date().getTime();
DELTA = T2 - T1;
console.log('It took '+DELTA+' milliseconds');
});
</script>
</body>
我创建了5个具有Lorem Ipsum和Lorem Pixel内容的通用元素,并将它们复制/粘贴3次,制作了15个第1级元素。
我隐藏了1000次并揭示了15个元素中的每一个。每次测试3次。
案例1 (目前为止获胜者):5.2s,4.75s,4.85s
案例2:21.5s,21.5s,20s
@edit 3:更改案例2方法
将第二种情况从hide()
/ show()
更改为css()
可以大幅提升效果。
//TEST 2: DOM
var _this,id;
$('div').each(function(){
_this = $(this);
_this.css('display','none');
id = _this.attr('id');
OBJ2.push(id);
});
var c;
for (var i = 0; i < 15000; i++) {
for(var k=0,l=OBJ2.length;k<l;k++){
c = $('#'+OBJ2[k]);
if(ACTIVE) ACTIVE.css('display','none');
c.css('display','block');
ACTIVE = c;
}
}
还将循环增加到15k。
案例1:大约6.5s
案例2:大约2.5s
答案 0 :(得分:4)
绝对将它留在DOM树中。我只想使用show / hide方法来显示你想要的那个。
如果存在应该反映在元素中的动态更改值,我只会使用JS方法,但如果它们都是静态的,那么更改DOM树的性能要高得多,而不仅仅是CSS样式更改。 / p>
您可以通过编写两者来测试,然后使用jsperf进行比较。
答案 1 :(得分:0)
Javascript是一种非常快速的语言,但DOM是一个巨大的瓶颈。因此,将数据放在Javascript对象中会快得多,但是您必须自己将活动元素呈现给DOM(而不是仅仅使其可见)。
我不担心DOM对于几十个元素的速度很慢,但是如果你有很多元素或者正在尝试对它们执行计算/过滤,那么一定要使用Javascript。
答案 2 :(得分:0)
我认为您可能想要应用延迟渲染的唯一dom元素是那些需要媒体内容(如图像,音频,视频等)的元素。对于那些,搜索一个延迟加载js库,在显示该元素时加载该元素的内容。你也可以将元素加载到页面中并隐藏起来,但也许如果媒体元素太多,那么内存的使用可能会很糟糕。
最后,您可以使用React.js,因为它的主要工作是在两个dom树之间进行差异渲染,这可能会在渲染相同dom元素的情况下给出一些很大的改进,但是内容略有不同。你可能知道这一点,你有什么理由决定在这个上完整的vainilla.js吗?