Dubrowsky
Хроники одного дупла
Блогово  →  WebDev  → 

Сборка DOM-дерева: производительность jQuery против innerHTML

21 Июня 2012 года

Как-то уже стало общем местом в наши дни, что "без jQuery мы никуда". Как же - ведь это удобно и... на этом мысль обрывается. А если кто-то вдруг заводит разговор о скорости, ему с умным видом отвечают заученной фразой с хабра: "железо стоит дешевле, чем часы работы программиста". И все к этому настолько привыкли, что тестировать "быстрый в написании" код на скорость как-то даже неприлично... однако я тут потестировал.

Потестировал даже не из-за сомнений в производительности, т.к. интерфейс не выглядел медленным на уровне ощущений. Для одной из рабочих задач хотелось переписать часть кода из соображений читаемости/поддерживаемости, и решил на всякий случай проверить, не будет ли новый вариант медленнее (мало ли).

Речь идет, конечно, не о "производительности jQuery вообще", а об одном маленьком аспекте - о способе сборки DOM-дерева через конструкции вида $('<div>ololo</div>');

Зачем такая штука может использоваться - примерно понятно. Мы создаем "кусок" дерева со всей мишурой, можем на него навешивать обрабочики и вообще всячески сопрягать "разметку" и "поведение" еще до того, как полученный "кусок" попадет в документ. Пишем метод get_form_field(), он нам возвращает что-то, что можно $.append(), и оно сразу будет реагировать на клики-киапы-блуры и т.д.

В качестве альтернативы я предложил собирать такие куски в строку по шаблону, вставлять в документ через innerHTML, а про обработчики париться уже отдельно (это тема другого разговора, там тоже есть чему тормозить).

Собственно, тест показал, что сборка в строку + innerHTML на довольно простом примере работает в десятки раз быстрее. В моем Firefox разница где-то в 20 раз. В вашем - смотрите сами. Вот ссылка на тест, любопытные - велкам в исходник. Кому лень - вот функции, которые гонялись. Повторюсь, код для сборки при помощи jQuery - почти настоящий, он очень похож на код из реального проекта, написанный хорошими толковыми парнями :)

jquery: function (data) {
	var form = $('<form />');
	for (var i in data) {
		var cf = data[i];
		var iid = 'inp_'+cf.name;
		var row = $('<div />').attr('class', 'form_row');
		var label = $('<label />').html(cf.label);
		label.attr('for', iid);
		row.append(label);
		var input_container = $('<div />');
		input_container.attr('class', 'input_container');
		row.append(input_container);
		var input = $('<input />');
		input.attr('id', iid);
		input.val(cf.value);
		input.attr('name', cf.name);
		input_container.append(input);
		form.append(row);
	}
	$('#target').append(form);
},
html: function(data) {
	var res = '<form>';
	for (var i in data) {
		var cf = data[i];
		var iid = 'inp_'+cf.name;
		res += '<div class="form_row">';
		res += '<label for="'+iid+'">'+cf.label+'</label>';
		res += '<div class="input_container">';
		res += '<input id="'+iid+'" name="'+cf.name+'" value="'+cf.value+'" />';
		res += '</div></div>'
	}
	res += '</form>';
	document.getElementById('target').innerHTML = res;
}

Делайте выводы. И да, обработчики - тема для отдельного разговора :) А на улице лето, и большинство граждан заботит вовсе не производительность JavaScript в разных ипостасях, а гораздо более радостные и насущные вещи, как то организация свадьбы по уму и по совести. Желаю всем счастья и здоровья.

Камменты

Сергей05.02.2013, 16:42#
Совершенно согласен с Вами. Саму недавно пришлось узнать о таком способе оптимизации (т.к. мне было нужно, чтобы в IE7 тоже быстро "условно" работало).
К Вашей функции html у меня есть одно замечание-предложение: вместо того, чтобы собирать строку с помощью суммирования, лучше использовать сборку через массив (в теле цикла: mas.push ('...подстрока...')) с последующим res = mas.join (''). В этом случае время сборки строки уменьшится ещё в 10-20 раз. А в старых браузерах это особенно важно, т.к. сборка строки там происходит ну очень медленно.
Дуброн самый15.02.2013, 04:19#
Сергей, спасибо, справедливое замечание! Да, в нашем проекте оно в конечном итоге именно так и работает.

Написать коммент: памятка постеру

 

Крутые посты wtf??? →

02.10.2012 · 93 каммента · рейтинг 16.18
27.06.2012 · 37 камментов · рейтинг 10.02
28.04.2008 · 44 каммента · рейтинг 8.72
06.03.2008 · 29 камментов · рейтинг 7.03
28.03.2008 · 24 каммента · рейтинг 6.42

Последне камменты

12.10.2019  6THFV6ZDSU0J 6THFV6ZDSU0J 6THFV6ZDSU0J www.yandex.ruДинамическая отправка формы с файлом в IE (ajax file upload + form.submit): S5yizZQjiS9
26.09.2019  5ZQMBL3RXY98 5ZQMBL3RXY98 5ZQMBL3RXY98 www.yandex.ruтам же: xwWbT1nO
26.09.2019  AT8LJX8SMJPE AT8LJX8SMJPE AT8LJX8SMJPE www.yandex.ruПочему не работает form.submit(): OuQnxIU8HYE
24.09.2019  2SSUSLMI 2SSUSLMI 2SSUSLMI www.yandex.ruтам же: 1DaGyZzh5
04.05.2019  Brian Fargoтам же: Спасибо. Все на поверхности, но фиг вкуришь с лету...

Статсы