Разгони свой сайт

Проект создан как справочный ресурс по методам уменьшения времени загрузки страницы и загрузки сайта у конечного пользователя

English Russian

Проверить скорость загрузки

http://

Оптимизация JavaScript часть 1: Добавление элементов DOM в документ

Многие Веб-разработчики пишут горы кода на 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). Почему я не говорю самый быстрый в случае с Firefox? Я добавил еще пару примеров, чтобы разъяснить ситуацию:

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('');

Вот результаты в виде таблицы и диаграммы.

NoMethodIE 6IE 7FF 1.5FF 2.0Opera 9
1createElement()140321916632863
2createElement() full1134----
3innerHTML39757207814105830793811391
4innerHTML optimized10994465010931
5innerHTML/join400314712531
 
6innerHTML/optimized+289341098417262
7innerHTML/join+9507811018962

Тест производительности: Добавление элементов DOM в документ

Рисунок 1. Тест производительности: Добавление элементов DOM в документ

Вы можете посмотреть тест и получить собственные результаты производительности здесь.

Выводы

  • Всегда используйте методы DOM, чтобы Ваш код соответствовал стандартам. Этот подход имеет удовлетворительную производительность и работает во всех браузерах.
  • Если Вам нужна самая высокая скорость, используйте подход join+innerHTML, который является самым быстрым в данном тесте.
  • Никогда не добавляйте строки HTML к innerHTML (даже если Вам нужно добавить маааааааленький элементик).
  • Opera — самый быстрый браузер в мире, но Internet Explorer 7 тоже довольно шустр, а вот Firefox 2.0 удивил своей низкой производительностью.
  • Никогда не верьте фанатикам вроде меня, и замеряйте производительность разных подходов сами (но не переживайте, Microsoft не проплатили мне рекламу своего браузера).
  • примечание от sunnybear: замена html.push на html[idx++] в последнем варианте (по Lecompte) позволяют выиграть до 50% в производительности (зафисировано для IE7)

Читать дальше

Все комментарии

Обратная связь

Если у вас возникли какие-либо вопросы или пожелания по работе Web Optimizator, пожалуйста, поделитесь ими, используя контактную информацию.

Спасибо за использование сервиса!

WEBO Site SpeedUp

Книги по оптимизации

Yet Another cSS selector

Ссылки по теме

Техника CSS sprites

Приемы для JavaScript

Хитрости для CSS

Облако сайтов

Вебсайтов сейчас: 1, сегодня: 410, всего: 136915, последний: webogroup.com
Если ты хороший дизайнер, файловик или оптимизатор - тебе сюда
© 2008–2010 sunnybear.ru | Карта сайта | RSS (читают 750)

This work is licensed under a Creative Commons Attribution 3.0 Unported License.