比较三种插入dom元素的方法+用jQuery mobile增强它们

Iaz*_*opI 5 javascript performance jquery jquery-mobile

将数据插入dom时,我遇到了性能问题.

在pagecontainerbeforeshow()事件,jQuery移动版本1.4.2上完成插入+ jQuery移动增强.

我试图通过比较我想要做的三个简化版本来看看哪种方法是最快的:

jQuery方法:

for(var i=0;i<2000;++i){
    $('<div>').attr({'data-role':'collapsible','id':'asdf'+i+''}).html('<h2>asdf</h2>').appendTo("#manage_content");
    $('<ul>').attr({'data-role':'listview'}).html('<li>bit</li>').appendTo('#asdf'+i+'');
    }
$('#manage').trigger('create');
Run Code Online (Sandbox Code Playgroud)

纯js,创建所有节点:

var d=document.createDocumentFragment();
var title,listitem,list;
var coll=new Array();
for(var i=0;i<2000;++i){
coll[i]=document.createElement('div');
coll[i].setAttribute("data-role", "collapsible");
title = document.createElement('h2');
title.innerHTML='asdf';
coll[i].appendChild(title);
list=document.createElement('ul');
list.setAttribute("data-role","listview");
listitem = document.createElement('li');
listitem.innerHTML='bit';
list.appendChild(listitem);
coll[i].appendChild(list);
d.appendChild(coll[i]);
}
document.getElementById("manage_content").appendChild(d);
$('#manage').trigger('create');
Run Code Online (Sandbox Code Playgroud)

jQuery大字符串:

var html='';
for(var i=0;i<2000;++i){
    html+='<div data-role="collapsible"><h2>asdf<h2><ul data-role="listview"><li>bit</li></ul></div>';
}
$('#manage_content').append(html);
$('#manage').trigger('create');
Run Code Online (Sandbox Code Playgroud)

令我惊讶的是,这样做的三种方式给出了相同的结果(大约7秒的执行时间......)

我做错了吗?有没有更好的办法?

我已经看到很多与此主题相关的问题,但大多数过时或说明纯javascript应该更快,对我来说情况并非如此.

没有jQuery增强功能:

  • jQuery标准:~400ms
  • 纯JS:~40ms
  • jQuery大字符串:~80ms
    所以即使读取/写入x_x很可怕,带文档片段的纯javascript也是最好的

    使用jQuery增强功能:

    在这里测试(@Omar的学分)

  • Iaz*_*opI 1

    假设仅使用 jquery mobile 进行 css 格式化,那么可以采取以下措施来加速 dom 插入 + 增强。

  • 对于插入部分:正如许多评论所暗示的那样,方法3似乎是最好的选择,因为方法2的微小性能增益不足以弥补其可读性的不足,这将使增强部分变成地狱......

  • 对于增强部分:
    -- 将所有 jquery mobile 类手动添加到 html 元素
    -- 不要添加任何 data-% 属性。
    -- 不要调用 $('your_page').trigger('create') 或 $('.ui-content').enhanceWithin()
    -- 而是手动添加所需的小部件事件。

    性能增益:

    通过常规的 jquery 移动增强功能,在我最坏的使用情况下,页面创建花费了2 秒。
    使用这种方法,大约需要50 毫秒...因此性能提高了 40 倍...

    下面的代码是两个嵌套的可折叠集和一个列表视图作为最后一个子项的示例案例(显然是我的)。如果有人感兴趣,我可以添加 jsperf x 次此元素插入+增强。

    小提琴: http: //jsfiddle.net/3pyRX/1/

    HTML:

    <div data-role='content'>
    
    <div class="ui-collapsible ui-collapsible-themed-content">
                            <h2 class="ui-collapsible-heading">
                            <a href="#" class="ui-collapsible-heading-toggle ui-btn ui-icon-plus ui-btn-icon-left ui-btn-b">Employee collapsible</a>
                            </h2>
                            <div class="ui-collapsible-content ui-body-inherit" style="display:none;">
                                <div class="ui-collapsible ui-collapsible-themed-content">
                                    <h2 class="ui-collapsible-heading">
                                    <a class="ui-collapsible-heading-toggle ui-btn ui-icon-plus ui-btn-icon-left ui-btn-b">
                                        <p class="inline">Child collapsible</p>
                                        <p class="inline coll_head_butt timecard ui-link ui-btn ui-btn-b ui-icon-check ui-btn-icon-notext ui-shadow ui-corner-all"></p>
                                    </a>
                                    </h2>
                                    <div class="ui-collapsible-content ui-body-inherit" style="display:none;">
                                        <ul class="ui-listview">
                                        <li class="projectxtask ui-li-has-count"><a class="ui-btn">li 1<span class="ui-li-count ui-body-inherit">42</span></a></li>
                                        <li><a class="ui-btn">li 2</a></li><li><a class="ui-btn">li 3</a></li>
                                        </ul>
                                    </div>
                                </div>
                            </div>
                        </div>
    </div>
    
    Run Code Online (Sandbox Code Playgroud)


    CSS:

    .projectxtask a{
    
        background-color:#33ccff !important;
        padding-right:2.6em !important;
        border-top:1px solid black !important;
        border-bottom:1px solid black !important;
    }
    .inline{display:inline !important;}
    
    
    .coll_head_butt{
        margin-left : 20px !important;
        border-style:none !important;
        box-shadow:none !important;
    }
    
    Run Code Online (Sandbox Code Playgroud)


    JS:

    $('.ui-collapsible-heading').on('click',function(event,ui){
    
        var coll_content = $(this).siblings();
        if(coll_content.is(":visible"))
            {$('a',this).removeClass( "ui-icon-minus" ).addClass( "ui-icon-plus" );
            coll_content.hide();}
        else
            {$('a',this).removeClass( "ui-icon-plus" ).addClass( "ui-icon-minus" );
            coll_content.show();}   
    });
    
    Run Code Online (Sandbox Code Playgroud)

    该代码写起来有点烦人,但如果您遇到与我的 jquery mobile 类似的性能问题,那么这是非常值得的。

    我在此示例中的可折叠标头内添加了图标,因为使用 jquery mobile,您将使用 <.a data-icon=check data-iconpos=notext data-role=button> 来获取图标按钮,这是不可能的没有 jquery 移动增强功能,因为 html 中不允许嵌套 <.a> 标签,并且浏览器会更正该标签。
    手动添加类时,像我在这里所做的那样,将 <.a> 替换为 <.p> 似乎可行。