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 · 90 камментов · рейтинг 18.93
15.02.2013 · 23 каммента · рейтинг 9.95
23.01.2013 · 20 камментов · рейтинг 9.22
06.03.2008 · 29 камментов · рейтинг 7.76
19.01.2008 · 20 камментов · рейтинг 6.4

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

22.07.2017  СергейПочему не работает form.submit(): Также столкнулся с неработающим .submit() при отпр...
20.07.2017  СергейСвязь: Здравствуйте. Хочу предложить Вам тройной обмен п...
17.07.2017  Илья АрхипкинСколько журналистов в России?: Мне рассказывали как журналисты освещали акцию в К...
21.05.2017  Vadim GukОбработка кликов и цели в Яндекс.Метрике, улучшенный вариант: Большое спасибо за решение задачи.
20.05.2017  ДмитрийТестовое задание для PHP-программиста (Junior): А джуны ещё нужны у вас в компании?

Статсы