【发布时间】:2016-01-08 04:43:20
【问题描述】:
就性能而言,在 DOM 树中包含 20 个元素(及其子元素)更好还是将所有内容存储在 Javascript 对象中?
案例一:
<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 对象中并在需要时删除并附加它们?
我该如何测试它?
@编辑 需要考虑的额外信息:
1- 所有元素都写入 HTML 文档,然后在页面加载时将其删除并存储在 javascript 对象中。
2- 每次活动元素更改时,我都会通过删除当前活动元素然后将新元素附加到它来更改 DOM 结构。
@EDIT 2:经过一些测试
这个想法是:有人将 HTML 元素写入 DOM,然后 Javascript 必须一次只显示/隐藏其中一个元素。这些元素有自己的孩子。它可以是整页网站或 Web 应用程序。
我创建了 2 个测试用例:
1- 元素将被移除,然后被 Javascript 多次重新附加。所以它们将被存储在一个 Javascript 对象中,直到它被召唤
2- 元素将在 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>
我用一些 Lorem Ipsum 和 Lorem Pixel 内容创建了 5 个通用元素,他们复制/粘贴了 3 次,形成了 15 个 1 级元素。
我隐藏和显露了 15 个元素中的每一个元素 1000 次。每次测试 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左右
【问题讨论】:
-
只有四个元素,没关系。当您进入数千个时,您可能会看到明显的差异。 Measure it 可以肯定。这里还有其他需要考虑的事情。例如,您的元素之一包含
img,因此您可能需要考虑是否要预加载图像资源。如果您使用脚本将img注入到 DOM 中,那么在将元素添加到 DOM 之前它不会开始加载。 -
有趣的结果。我还发现
css('display')比show()/hide()快得多。这是我正在玩的性能测试;它比您的情况更简单,但仍然强调在这种情况下使用css()显示/隐藏比删除和附加效果更好。见 jsperf:jsperf.com/dynamic-dom-performance -
在 Chrome、Firefox、IE 和 Edge 中看到一致的结果。 (有趣;browserscope 将 Edge 检测为 Chrome 42)
标签: javascript jquery html performance dom