Оптимизация JavaScript. Часть 1: Добавление элементов DOM в документ (исходники)Источник: kpumuk
Многие Веб-разработчики пишут горы кода на JavaScript, особенно в новом веке Web 2.0. Это мощная технология, но большинство браузеров содержат очень медленную реализацию движка, и многим в какой-то момент приходится пересматривать код и пытаться сделать его быстрее. В этой заметке я поделюсь своим опытом и покажу несколько трюков, которые помогут сделать Ваш код JavaScript таким быстрым, насколько это возможно. Это первая статья из серии, будьте на связи. Сценарий: Вы разрабатываете мощное приложение для Интернет, и Вам нужно динамически загрузить элементы, используя AJAX, добавив их в текущий документ. По какой-то причине Вы не хотите (или не можете) использовать полностью сформированный HTML, и получаете данные в массив JavaScript. Я знаю два классических способах выполнить такую задачу: создать элементы, используя метод document.createElement(), и склеить HTML в строку, присвоим ее свойству parentElement.innerHTML. Конечно, Вы можете комбинировать оба способа. Рассмотрим эти подходы более детально. Классический способ (и в идеальном мире - лучший) - использовать DOM для манипуляций над элементами: for (var i = 1; i <= 1000; i++) { var li = document.createElement('li') li.appendChild(document.createTextNode('Element ' + i)) el.appendChild(li); } Не такая уж и плохая производительность. Internet Explorer 6 самый медленный - 1403 мс (но ведь это самый медленный браузер в мире, правда?), остальные же браузеры справились довольно шустро ( 63 - 328 мс ). Ладно, но как насчет создания элемента DOM прямо из кода HTML? for (var i = 1; i <= 1000; i++) { var li = document.createElement('<li>Element ' + i + '</li>') el.appendChild(li); } Работает значительно лучше в Internet Explorer 6 ( 1134 мс ), но вообще не работает в других браузерах. Блин! Конечно, Вы можете добавить блок try/catch и создать элементы, используя первый подход в блоке catch для остальных браузеров. Но у меня есть решение получше. Every DOM node has attribute innerHTML which holds all child nodes as HTML string. el.innerHTML = ''; for (var i = 1; i <= 1000; i++) { el.innerHTML += '<li>Element ' + i + '</li>'; } Вау, я сильно удивлен, насколько медленной может быть процедура добавления элементов ( 11391 - 307938 мс )! Забавный результат, не правда ли? А все оттого, что браузеры пытаются отрисовать список после каждого обновления, и это сильно замедляет работу. Небольшая оптимизация: var html = ''; for (var i = 1; i <= 1000; i++) { html += '<li>Element ' + i + '</li>'; } el.innerHTML = html; Все браузеры показали отличный результат ( 31 - 109 мс ), но Internet Explorer по-прежнему медленный - 10994 мс . Я нашел решение, которой работает очень быстро во всех браузерах: создать массив кусков HTML, и затем склеить его используя пустую строку в качестве разделителя: var html = []; for (var i = 1; i <= 1000; i++) { html.push('<li>Element '); html.push(i); html.push('</li>'); } el.innerHTML = html.join(''); Это самый быстрый подход для Internet Explorer 6 - 400 мс , и довольно быстрый для остальных браузеров ( 31 - 125 ms ). Why I’m not saying fastest in case of Firefox? I added another test to make in cleaner: var html = ''; for (var i = 1; i <= 1000; i++) { html += '<li style="padding-left: ' + (i % 50) + '" id="item-' + i + '">Element ' + i + ' Column ' + (i % 50) + '</li>'; } el.innerHTML = html; И второй пример: var html = []; for (var i = 1; i <= 1000; i++) { html.push('<li style="padding-left: '); html.push(i % 50); html.push('" id="item-'); html.push(i); html.push('">Element '); html.push(i); html.push(' Column '); html.push(i % 50); html.push('</li>'); } el.innerHTML = html.join(''); Вот результаты в виде таблицы и диаграммы.
Вы можете посмотреть тест и получить собственный результаты производельности здесь. Выводы
|