Сравнение трех способов вставки элементов dom их улучшение с помощью jQuery mobile

#javascript #jquery #performance #jquery-mobile

#javascript #jquery #Производительность #jquery-mobile

Вопрос:

У меня возникают проблемы с производительностью при вставке данных в dom.

Вставки улучшение jQuery для мобильных устройств, выполненное на событии pagecontainerbeforeshow (), версия jQuery для мобильных устройств 1.4.2.

Я попытался определить, какой подход будет самым быстрым, сравнив три упрощенные версии того, что я хочу сделать:

Подход 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');
  

Чистый 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');
  

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');
  

К моему удивлению, три способа сделать это дают одинаковый результат (время выполнения около 7 секунд …)

Я делаю что-то из этого неправильно? Есть ли лучший способ?

Я видел много вопросов, связанных с этой темой, но в основном устаревших или утверждающих, что чистый javascript должен быть быстрее, что не относится ко мне.

Без улучшения jQuery :

  • Стандарт jQuery: ~ 400 мс
  • Чистый JS: ~ 40 мс
  • Большая строка jQuery: ~ 80 мс
    , поэтому чистый javascript с фрагментами документа является лучшим, даже несмотря на то, что чтение / запись x_x ужасно

    С улучшением jQuery :

    Тест здесь (кредиты @Omar)

  • Комментарии:

    1. Сколько всего вставлено узлов? 7 секунд кажется много. Вы пробовали профилировать его?

    2. По моему мнению, около 8000. Однако во всех трех примерах, которые я себе представляю, происходит много перепрошивки.

    3. Запустите процесс во время профилирования, чтобы узнать, где тратится больше всего времени.

    4. Согласно этому тесту , ваш 2-й и 3-й код самые быстрые. Однако обратите внимание, что .trigger("create") это устарело и заменено на .ehanceWithin() . Редактировать: .enhanceWithin() быстрее, чем .trigger("create") .

    5. Что вы можете сделать, так это добавлять классы статически, а их события привязывать вручную, чтобы сворачивать / разворачивать сворачиваемые объекты. Если вы хотите, я могу написать ответ для вас.

    Ответ №1:

    Вот что можно сделать, чтобы ускорить вставку dom улучшение, предполагая, что jquery mobile используется только для форматирования css.

  • Что касается части вставки: как показывают многие комментарии, метод 3 кажется лучшим вариантом, потому что небольшого прироста производительности метода 2 недостаточно, чтобы компенсировать его недостаточную читаемость, что превратило бы часть улучшения в ад…

  • Для части улучшения :
    — Добавьте все классы jquery mobile вручную в элементы html
    — не добавляйте никаких атрибутов data-%.
    — Не вызывайте $(‘your_page’).trigger(‘create’) или $(‘.ui-content’).enhanceWithin()
    — Вместо этого добавляйте нужные события виджета вручную.

    Прирост производительности :

    При обычном улучшении jquery mobile создание страницы заняло 2 секунды в моем худшем случае использования.
    При использовании этого метода это составляет около 50 мс … так что производительность увеличивается на 40 *…

    Приведенный ниже код предназначен для примера (очевидно, моего) двух вложенных collapsiblesets и listview в качестве последнего дочернего элемента. Если кому-то интересно, я мог бы добавить 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>
      

    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;
    }
      

    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();}   
    });
      

    Код немного раздражает при написании, но если у вас такие же проблемы с производительностью, как у моего jquery mobile, оно того стоит.

    Я добавил значок внутри сворачиваемого заголовка в этом примере, потому что с jquery mobile вы бы использовали <.a data-icon=check data-iconpos=notext data-role=button>, чтобы получить значок кнопки, что невозможно сделать без улучшения jquery mobile, потому что вложенный <.a>теги не разрешены в html и будут исправлены браузером.
    При ручном добавлении классов замена <.a> на <.p>, как я сделал здесь, похоже, работает.

  • Комментарии:

    1. Нет проблем ответить на ваш собственный вопрос. Но если то, что вы опубликовали в качестве ответа, является лишь дополнением к вопросу, тогда вам следует отредактировать вопрос и удалить ответ.