Оптимізація 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). 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(“”);

Ось результати у вигляді таблиці і діаграми.







































































No


Method


IE 6


IE 7


FF 1.5


FF 2.0


Opera 9

1 createElement()  1403 219 166 328 63
2 createElement() full  1134
3 innerHTML  39757 20781 41058 307938 11391
4 innerHTML optimized  10994 46 50 109 31
5 innerHTML/join  400 31 47 125 31
 
6 innerHTML/optimized+  28934 109 84 172 62
7 innerHTML/join+  950 78 110 189 62


Ви можете подивитися тест і отримати власний результати проізводельності тут.


Висновки


Частина 2


Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*