哪个更适合性能,DOM或Javascript对象中的元素?

时间:2015-10-10 07:59:35

标签: javascript jquery html performance dom

就性能而言,在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

3 个答案:

答案 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吗?