В последнее время я делал много всплывающих окон модальных окон, а для этого я использовал jQuery. Метод, который я использовал для создания новых элементов на странице, в подавляющем большинстве был примерно таким:
$("<div></div>");
Однако у меня такое чувство, что это не лучший и не самый эффективный способ сделать это. Как лучше всего создавать элементы в jQuery с точки зрения производительности?
У Этот ответ есть тесты для приведенных ниже предложений.
Остерегайтесь преждевременной оптимизации - если вы не делаете этого для сотен элементов DOM за раз или используете ОЧЕНЬ старые браузеры, то вы, вероятно, не заметите никакой разницы в производительности браузера.
@Blazemonger Не то чтобы я использовал нужный как более эффективный метод создания элементов DOM, но ситуация, в которой я оказался, заставила меня задуматься, какие есть альтернативы и насколько они эффективны.
jQuery - это библиотека - по этой причине вы почти всегда будете нести накладные расходы: это как разговаривать с кем-то через интерпретатор. Если вы не хотите использовать необработанный JavaScript, воспользуйтесь преимуществом того, насколько быстро он напишет $ ('<div>') и примите снижение производительности.
Что значит «мелочь»?
действительно ли это имеет значение, если бы html-разработчики так заботились об эффективности, они бы спросили, почему они не могут создать несколько элементов одновременно, вместо того, чтобы спрашивать dom по одному. Здесь нет выигрыша. Этот вопрос слишком субъективен, потому что вы просите сделать что-то изначально неэффективное эффективно (что более эффективно, поездка в школу на реактивном самолете или использование катапульты?). честно говоря, ваше намерение уникально, и существует гипотетический синтаксический анализатор, который всегда будет компилировать то, что вы намерены, в document.createElement ('div') независимо от того, как вы это делаете.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Я думаю, вы используете лучший метод, хотя вы можете оптимизировать его для:
$("<div/>");
лично я бы предложил (для удобочитаемости):
$('<div>');
некоторые цифры по предложениям на данный момент (safari 3.2.1 / mac os x):
var it = 50000;
var start = new Date().getTime();
for (i = 0; i < it; ++i) {
// test creation of an element
// see below statements
}
var end = new Date().getTime();
alert( end - start );
var e = $( document.createElement('div') ); // ~300ms
var e = $('<div>'); // ~3100ms
var e = $('<div></div>'); // ~3200ms
var e = $('<div/>'); // ~3500ms
Из документации jquery: «При создании отдельных элементов используйте закрывающий тег или формат XHTML. Например, для создания диапазона используйте $ ("<span />") или $ ("<span> </span>") вместо закрывающей косой черты / тега. '
Я предположил, что это устарело, поскольку метод, который я описываю, создает такой же действительный XHTML. пример: var e = $ ('<div>') .append ($ ('<div>')). html (); предупреждение (е); есть ли какой-нибудь другой показатель, который сделает этот метод непригодным для использования?
@Owen, такое поведение - ошибка, а не особенность. Мусор на входе, мусор на выходе - так уж получилось, что мусор, который вы получаете, приемлемый. Однако не полагайтесь на него между версиями jQuery, если только спецификация функции не изменится.
Как и ожидалось, аналогичные числа наблюдаются в Mac OS X Chrome (100 мс для createElement () против 500 мс при разборе текста) и Mac OS X Firefox (350 мс против 1000 мс). Спасибо, что написали тестовый цикл.
@tvanfosson Очевидно, это изменилось, в текущих документах говорится: «Когда параметр имеет единственный тег (с необязательным закрывающим тегом или быстрым закрытием) - $ (" <img /> ") или $ (" <img> " ), $ ("<a> </a>") или $ ("<a>") - jQuery создает элемент с помощью встроенной функции JavaScript createElement (). "
@metatron Я знаю, что это старый вопрос, но есть ли у вас ссылка на документы, в которых это сказано? Не сомневаюсь в вас, просто хотел бы иметь первоисточник ..
@MarcStober Без обид. Он все еще здесь: http://api.jquery.com/jQuery/#jQuery2. В документах упоминается необязательный закрывающий тег или быстрое закрытие
Я использую $(document.createElement('div'));Бенчмаркинг показывает, эта техника самая быстрая. Я предполагаю, что это потому, что jQuery не должен идентифицировать его как элемент и создавать сам элемент.
Вам действительно следует запускать тесты с разными движками Javascript и взвешивать свою аудиторию с результатами. Принимайте решение оттуда.
jQuery «добавляет» его в DOM? Где? Для меня это не имеет особого смысла - куда подевался бы div?
созданный div в jquery должен быть добавлен так же, как и в javascript. $ ('<div>') сам по себе не прикрепляется к DOM, пока вы не добавите его к чему-либо.
@tvanfosson: Извини, дружище, ты снова ошибаешься. Если вы хотите, чтобы эта часть $(document.createElement('div')) была добавлена в DOM, вам нужно будет добавить или добавить ее к другому элементу (уже в DOM). Как бы то ни было, созданный jquery элемент НЕ привязан ни к чему (по крайней мере, в современных браузерах, поддерживающих documentFragment, AFAIK).
@ Дэвид - очевидно, ты прав. Замечу, что я добавил комментарий около 2 лет назад, когда только начинал изучать jQuery. Вам нужно будет сделать appendTo, ... Поскольку комментарии были явно неправильными, я удалил их.
Справочник по тестированию отличный, но он также тестирует создание десятков тысяч элементов. Когда вы КОГДА-ЛИБО столкнетесь с таким количеством элементов в типичной ситуации? Скорее всего, вам нужно беспокоиться о более серьезных вещах, чем создание элемента. document.createElement «Выполнено 39 682 раза за 0,097 секунды», тогда как $ ('<div>') «Выполнено 12 642 раза за 0,068 секунды». Я бы сказал, что если что-то может работать тысячи раз менее чем за секунду, вы в безопасности.
Кроме того, использование $ (document.createElement ('div')); Я бы сказал, что он менее эффективен, потому что на написание уходит больше времени из-за очень крошечной выгоды, которую вы получите в браузере, если создаете только один элемент за раз здесь и там. Технически сам jQuery менее эффективен как библиотека из-за затрат на поиск и накладных расходов, которые вы несете при его использовании. Если кто-то так намерен сэкономить драгоценные тысячные доли миллисекунды, используя document.createElement вместо $ ('<div>'), тогда им не следует использовать jQuery:], потому что $ ('<div>') это одна из причин, по которой вы его используете!
Кроме того, сэкономленная доля миллисекунды, вероятно, будет многократно потеряна из-за увеличения времени загрузки пары дополнительных байтов, добавляемых более длинным кодом.
Еще один момент: если вам нужен конечный тег, например $("<div>something</div>"), некоторые валидаторы javascript будут жаловаться на него, потому что строка </ может сломать парсеры html.
@fettereddingoskidney Хотя, в центре внимания вопрос производительности является, и даже если это не распространено, есть абсолютно случаи, когда вам нужно создать многие тысячи элементов, где заметная здесь разница в производительности значительна.
Например: это может произойти с элементами td, поскольку их может быть довольно много в большой таблице.
К вашему сведению, у меня был тот же вопрос, и я создал аналогичный тест, но для более сложных элементов с несколькими дочерними элементами: jsperf.com/jquery-multi-element-creation
Я провел тест, и разница составила около 5% в Chrome, для удобства других.
Извините, вопрос новичка: не могли бы вы объяснить, где этот div будет создан на странице? Сейчас мне кажется, что он создан где-то на странице, чтобы я не мог контролировать, где на странице будет отображаться вновь созданный элемент.
@Andreas "Не могли бы вы объяснить, где этот div будет создан на странице?" $ (document.createElement ('div')); создаст <div>, но не поместит его на вашу страницу. Вы хотите вызвать .appendTo (или аналогичный метод), указав, где именно вы хотите разместить новый элемент: api.jquery.com/category/manipulation/dom-insertion-inside
У меня вопрос ... Могу ли я вызвать событие click для этого элемента, не добавляя его в Dom ?? Представьте, что это тег <a>.
Вам не нужна чистая производительность от операции, которую вы будете выполнять крайне редко с точки зрения ЦП.
Зависит от того, как часто вы это делаете.
OP создает модальное всплывающее окно. Эта операция не повторяется тысячи раз в секунду. Вместо этого он повторяется, может быть, раз в несколько секунд максимум. Использование метода jQuery(html :: String) совершенно нормально. Если ситуация не является чрезвычайно необычной, вряд ли удастся добиться лучшей производительности воспринимается. Потратьте энергию на оптимизацию на случаи, в которых она могла бы использоваться. Кроме того, jQuery оптимизирован по скорости во многих отношениях. Делайте с ним разумные вещи и доверяйте, но проверяйте, чтобы оно было быстрым.
Если у вас много содержимого HTML (больше, чем один div), вы можете подумать о том, чтобы встроить HTML в страницу в скрытом контейнере, а затем обновить его и сделать видимым, когда это необходимо. Таким образом, большая часть вашей разметки может быть предварительно проанализирована браузером и избежать увязки JavaScript при вызове. Надеюсь это поможет!
Спасибо за совет. Я использовал этот подход раньше, однако в данном конкретном случае я особенно хочу знать о создании элементов.
Это неправильный ответ на вопрос, но все же я хотел бы поделиться этим ...
Использование только document.createElement('div') и пропуск JQuery значительно улучшит производительность, если вы хотите на лету создавать множество элементов и добавлять их в DOM.
На самом деле, если вы используете $('<div>'), jQuery также будет использовать document.createElement().
(Просто взгляните на строка 117).
Есть некоторые накладные расходы на вызов функций, но если производительность не критична (вы создаете сотни [тысячи] элементов), нет особых причин возвращаться к простому ДОМ.
Просто создание элементов для новой веб-страницы - это, вероятно, тот случай, когда вам лучше всего будет придерживаться способа jQuery.
Во-первых, это может быть проще:
$("<div class=foo id=bar style='color:white;bgcolor:blue;font-size:12pt'></div>")
Затем сделать все это с помощью вызовов jquery.
Кто-то уже сделал тест: Эквивалент jQuery document.createElement?
$(document.createElement('div')) - большой победитель.
Вы должны понимать, что значение производительности при создании элементов не имеет значения в контексте использования jQuery в первую очередь.
Имейте в виду, что нет никакой реальной цели в создании элемента, если вы на самом деле не собираетесь его использовать.
У вас может возникнуть соблазн протестировать производительность чего-то вроде $(document.createElement('div')) vs. $('<div>') и получить значительный прирост производительности от использования $(document.createElement('div')), но это всего лишь элемент, которого еще нет в DOM.
Однако, в конце концов, вы все равно захотите использовать этот элемент, поэтому настоящий тест должен включать f.ex. .добавить в();
Давайте посмотрим, если вы протестируете следующее друг против друга:
var e = $(document.createElement('div')).appendTo('#target');
var e = $('<div>').appendTo('#target');
var e = $('<div></div>').appendTo('#target');
var e = $('<div/>').appendTo('#target');
Вы заметите, что результаты будут разными. Иногда один способ работает лучше, чем другой. И это только потому, что количество фоновых задач на вашем компьютере со временем меняется.
Итак, в конце концов, вы хотите выбрать самый маленький и наиболее читаемый способ создания элемента. Таким образом, по крайней мере, ваши файлы сценариев будут минимально возможными. Вероятно, более значительный фактор для оценки производительности, чем способ создания элемента до его использования в DOM.
Я знаю, что это старый, но в первом примере нет необходимости в jQuery: document.getElementById('target).appendChild(document.createElement('div'));
What is the most efficient way to create HTML elements using jQuery?
Поскольку речь идет о jQuery, я думаю, что лучше использовать этот (чистый) подход (вы используете)
$('<div/>', {
'id':'myDiv',
'class':'myClass',
'text':'Text Only',
}).on('click', function(){
alert(this.id); // myDiv
}).appendTo('body');
Таким образом, вы даже можете использовать обработчики событий для определенного элемента, например
$('<div/>', {
'id':'myDiv',
'class':'myClass',
'style':'cursor:pointer;font-weight:bold;',
'html':'<span>For HTML</span>',
'click':function(){ alert(this.id) },
'mouseenter':function(){ $(this).css('color', 'red'); },
'mouseleave':function(){ $(this).css('color', 'black'); }
}).appendTo('body');
Но когда вы имеете дело с большим количеством динамических элементов, вам следует избегать добавления события handlers в конкретный элемент, вместо этого вы должны использовать делегированный обработчик событий, например
$(document).on('click', '.myClass', function(){
alert(this.innerHTML);
});
var i=1;
for(;i<=200;i++){
$('<div/>', {
'class':'myClass',
'html':'<span>Element'+i+'</span>'
}).appendTo('body');
}
Итак, если вы создаете и добавляете сотни элементов с одним и тем же классом, то есть (myClass), то для обработки событий будет потребляться меньше памяти, потому что только один обработчик будет выполнять работу для всех динамически вставляемых элементов.
Обновлять : Поскольку мы можем использовать следующий подход для создания динамического элемента
$('<input/>', {
'type': 'Text',
'value':'Some Text',
'size': '30'
}).appendTo("body");
Но атрибут size не может быть установлен с использованием этого подхода с использованием jQuery-1.8.0 или более поздней версии, и вот старый отчет об ошибке, посмотрите на этот пример с использованием jQuery-1.7.2, который показывает, что атрибут size установлен на 30, используя приведенный выше пример, но с использованием того же подхода мы не можем установить size атрибут с использованием jQuery-1.8.3, вот нерабочая рабочий пример. Итак, чтобы установить атрибут size, мы можем использовать следующий подход
$('<input/>', {
'type': 'Text',
'value':'Some Text',
attr: { size: "30" }
}).appendTo("body");
Или этот
$('<input/>', {
'type': 'Text',
'value':'Some Text',
prop: { size: "30" }
}).appendTo("body");
Мы можем передать attr/prop как дочерний объект, но он работает в версиях jQuery-1.8.0 and later, проверьте этот пример, но это не будет работать в jQuery-1.7.2 or earlier (не тестировалось во всех более ранних версиях).
Кстати, взято из отчета об ошибке jQuery
There are several solutions. The first is to not use it at all, since it doesn't save you any space and this improves the clarity of the code:
Они посоветовали использовать следующий подход (также работает в более ранних, протестирован в 1.6.4)
$('<input/>')
.attr( { type:'text', size:50, autofocus:1 } )
.val("Some text").appendTo("body");
Так что лучше использовать этот подход, ИМО. Это обновление сделано после того, как я прочитал / нашел этот ответ, и в этом ответе показано, что если вы используете 'Size'(capital S) вместо 'size', тогда он будет просто работать нормально, даже в version-2.0.2
$('<input>', {
'type' : 'text',
'Size' : '50', // size won't work
'autofocus' : 'true'
}).appendTo('body');
Также читайте про опора, потому что есть разница, Attributes vs. Properties, он меняется в зависимости от версии.
Что это за синтаксис $ ('<div />', {.........}), я искал его и нашел похожий, используя $ ('<div>) .attr ( {......})?
@RafaelRuizTabares, в $('<div>', {...}) вы передаете объект, который содержит все атрибуты, а в $('<div>').attr({...}) вы создаете элемент без каких-либо атрибутов, но позже устанавливаете атрибуты с помощью метода attr().
@TheAlpha где я могу найти информацию о том, что я могу написать внутри {}? Потому что я вижу, что это атрибуты и события, но для <div> вы тоже используете html. Спасибо!
Поиск по сайту jQuery.com может оказаться полезным @RafaelRuizTabares или погуглить :-)
Это, безусловно, самый чистый и читаемый способ! Вероятно, не самый быстрый способ, но, безусловно, меньше ошибок при добавлении строки. Спасибо @TheAlpha
Я использую jquery.min v2.0.3. Мне лучше использовать следующее:
var select = jQuery("#selecter");
jQuery("`<option/>`",{value: someValue, text: someText}).appendTo(select);
следующим образом:
var select = jQuery("#selecter");
jQuery(document.createElement('option')).prop({value: someValue, text: someText}).appendTo(select);
Время обработки первого кода намного меньше, чем второго.
Поэкспериментируйте и с удалением стилей и посмотрите, ускорит ли это процесс. Я считаю, что приложение CSS и обновления для меня больше всего замедляют работу на больших страницах.