#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 :
, поэтому чистый 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.
— Добавьте все классы 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. Нет проблем ответить на ваш собственный вопрос. Но если то, что вы опубликовали в качестве ответа, является лишь дополнением к вопросу, тогда вам следует отредактировать вопрос и удалить ответ.