Высокопроизводительные AJAX-приложения. Часть 4

Высокопроизводительный динамический HTML

Изменение дерева документа при помощи innerHTML

var i, j, el, table, tbody, row, cell; el = document.createElement("div"); document.body.appendChild(el); table = document.createElement("table"); el.appendChild(table); tbody = document.createElement("tbody"); table.appendChild(tbody); for (i = 0; i < 1000; i++) {     row = document.createElement("tr");     for (j = 0; j < 5; j++) { 	cell = document.createElement("td"); 	row.appendChild(cell);     }     tbody.appendChild(row); }

(сильно быстрее во всех браузерах класса А)

var i, j, el, idx, html; idx = 0; html = []; html[idx++] = "<table>"; for (i = 0; i < 1000; i++) {     html[idx++] = "<tr>";     for (j = 0; j < 5; j++) { 	html[idx++] = "<td></td>";     }     html[idx++] = "</tr>"; } html[idx++] = "</table>"; el = document.createElement("div"); document.body.appendChild(el); el.innerHTML = html.join("");

Замечание: прочитайте http://www.julienlecomte.net/blog/2007/12/38/

Изменение дерева документа при помощи cloneNode

var i, j, el, table, tbody, row, cell; el = document.createElement("div"); document.body.appendChild(el); table = document.createElement("table"); el.appendChild(table); tbody = document.createElement("tbody"); table.appendChild(tbody); for (i = 0; i < 1000; i++) {     row = document.createElement("tr");     for (j = 0; j < 5; j++) { 	cell = document.createElement("td"); 	row.appendChild(cell);     }     tbody.appendChild(row); }

(быстрее по всех браузерах класса А, иногда значительно быстрее)

var i, el, table, tbody, template, row, cell; el = document.createElement("div"); document.body.appendChild(el); table = document.createElement("table"); el.appendChild(table); tbody = document.createElement("tbody"); table.appendChild(tbody); template = document.createElement("tr"); for (i = 0; i < 5; i++) {     cell = document.createElement("td");     template.appendChild(cell); } for (i = 0; i < 1000; i++) {     row = template.cloneNode(true);     tbody.appendChild(row); }

Замечание: расширенные свойства (expando properties) и прикрепленные обработчики событий будут утеряны!

Изменение дерева документа при помощи DocumentFragment

  • DocumentFragment (DOM Level 1 Core) является облегченным вариантом Document.
  • Он поддерживает только ограниченное число обычных DOM-методов и свойств.
  • Реализация в IE интерфейса для DocumentFragment не соответствует спецификации W3C и возвращает обычный объект Document.

var i, j, el, table, tbody, row, cell, docFragment; docFragment = document.createDocumentFragment(); el = document.createElement("div"); docFragment.appendChild(el); table = document.createElement("table"); el.appendChild(table); tbody = document.createElement("tbody"); table.appendChild(tbody); for (i = 0; i < 1000; i++) {     ... } document.body.appendChild(docFragment);

Уменьшайте число обработчиков событий (½)

  • Прикрепление обработчика событий к сотням элементов весь ресурсоемко
  • Наращивание количества обработчиков событий чревато потенциальными утечками памяти
  • Решение: использовать event delegation, технику, базирующуюся на event bubbling

<div id="container">     <ul> 	<li id="li-1">List Item 1</li> 	<li id="li-2">List Item 2</li> 	<li id="li-3">List Item 3</li> 	<li id="li-4">List Item 4</li> 	<li id="li-5">List Item 5</li> 	...     </ul> </div>

Уменьшайте число обработчиков событий (2/2)

YAHOO.util.Event.addListener("container", "click", function (e) {			         var el = YAHOO.util.Event.getTarget(e);     while (el.id !== "container") { 	if (el.nodeName.toUpperCase() === "LI") { 	    // Что-нибудь делаем... 	    break; 	} else { 	    el = el.parentNode; 	}     } });

Уменьшайте отрисовки (reflows)

  • Отрисовка экрана происходит каждый раз при манипуляциях с DOM-деревом.
  • У браузеров есть ряд оптимизаций, чтобы уменьшить число отрисовок, в частности:
    • Изменение невидимого элемента (display:none) не вызывают отрисовку
    • Изменение элемента, не входящего в DOM («off-DOM») не вызывает отрисовку
  • Групповое изменение стилей:
    • Изменяйте значение атрибута style при помощи метода setAttribute (не работает в Internet Explorer). Пример:

      el.setAttribute("style", "display:block;width:auto;height:100px;...");
    • Изменяйте значение свойства cssText объекта style. Пример:

      el.style.cssText = "display:block;width:auto;height:100px;...";
    • Более масштабируемо: изменяйте название CSS класса у элемента. Пример:

      YAHOO.util.Dom.replaceClass(el, "foo", "bar");

Разные советы...

  • Может быть, стоит использовать событие onmousedown вместо onclick
    • Используйте как преимущество удаление небольшой задержки между нажатием кнопки мыши и ее освобождением пользователем.
  • «Переключите ваш код на первую передачу»: устраните частые и ресурсоемкие действия
    • Смотрите http://yuiblog.com/blog/2007/07/09/downshift-your-code/


Запись навигация

Top