Разгони свой сайт Лекция 8: Быстрый JavaScript webo.in Мациевский Николай

advertisement
Разгони свой сайт
Лекция 8: Быстрый JavaScript
Мациевский Николай
webo.in
1 / 24
Содержание
•
•
•
•
•
Замыкания и утечки памяти
«Тяжелые» JavaScript-вычисления
Быстрый DOM
Кэширование в JavaScript
Элементарные операции
webo.in
2 / 24
Замыкания и утечки памяти
webo.in
3 / 24
Шаблоны утечек
•
•
•
•
Циклические ссылки
Замыкания
Постраничные утечки
Псевдо-утечки
webo.in
4 / 24
Циклические ссылки
• Объект из области JavaScript создает
ссылка на DOM-узел
• DOM-узел создает ссылку на другой
объект JavaScript
• Сборка мусора
• Объект JavaScript ждет DOM-узел
• DOM-узел ждет другой объект JavaScript
webo.in
5 / 24
Замыкания
• JavaScript объект создает замыкание
• DOM-узел обращается к этому
замыканию
• JavaScript снимает ссылку с замыкания
• Замыкание живет, поскольку нужно
DOM-узлу
• Сборщик мусора не отслеживает такие
ссылки
webo.in
6 / 24
Постраничные утечки
• Порядок добавления элементов в
DOM-дерево играет значение
• Промежуточные узлы создают
«миниутечки»
• Добавление узлов непосредственно к
текущему дереву не «течет»
webo.in
7 / 24
Псевдо-утечки
• Выделение памяти для кэша
DOM-узлов
• Выделение памяти для глобальных
объектов
• Выделение памяти под замыкания
• Все это не утечки, а особенности
функционирования JavaScript
webo.in
8 / 24
«Тяжелые»
JavaScript-вычисления
webo.in
9 / 24
Ограничение на выполнение
• Есть предел выполнения JavaScript
• Время выполнения (Mozilla)
• Число элементарных операций (IE)
• Выделяемая память (Firefox)
• Мобильные агенты гораздо «слабее»
настольных компьютеров
webo.in
10 / 24
Обратная связь
• Рекурсивное выполнение
• arguments.callee
• + setTimeout( , 0)
• Браузер останавливает поток и
проверяет состояние
• Получаем интерактивное выполнение
webo.in
11 / 24
Улучшаем шаблон
• Интерактивность и накладные расходы
• Группировка итераций
• В setTimeout не строка, а вызов
функции
• Синхронизация глобальных
переменных
webo.in
12 / 24
Быстрый DOM
webo.in
13 / 24
DocumentFragment
• Поддерживается в IE6+
• Позволяет создать фрагмент дерева
• Быстрее для элементарных операций
var div = document.getElementsByTagName("div");
var fragment = document.createDocumentFragment();
for ( var e = 0; e < elems.length; e++ ) {
fragment.appendChild( elems[e] );
}
for ( var i = 0; i < div.length; i++ ) {
div[i].appendChild( fragment.cloneNode(true) );
}
webo.in
14 / 24
innerHTML
• innerHTML быстрее DOM-методов
• Передаваемый HTML нужно фильтровать
var i, j, el, 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("");
webo.in
15 / 24
Кэширование в JavaScript
webo.in
16 / 24
Необходимость кэширования
•
•
•
•
Сложная клиентская логика = 50-500 мс
Серверные запросы = 50-200 мс
DOM-вызовы = 1-10 мс
Доступ к глобальным
объектам = 0.1-1 мс
• Но! Большое число объектов замедляет
обращение к каждому
webo.in
17 / 24
Кэширование вызовов
• В локальные переменные
var arr = document.getElementsByTagName(‘*’);
var globalVar = 0;
(function () {
var i, l, localVar;
l = arr.length;
localVar = globalVar;
for (i = 0; i < l; i++) {
localVar++;
}
globalVar = localVar;
})();
webo.in
18 / 24
Кэширование DOM-узлов
• В локальные переменные
var arr = document.getElementsByTagName(‘*’);
var globalVar = 0;
(function () {
var i, l, localVar;
l = arr.length;
localVar = globalVar;
for (i = 0; i < l; i++) {
localVar++;
}
globalVar = localVar;
})();
webo.in
19 / 24
Кэширование цепочек
• Такой пример
for (i=0; i < 10000; i++) a.b.c.d(v);
• будет выполняться медленнее, чем
var f=a.b.c.d;
for (i=0; i < 10000; i++) f(v);
• или
var f=a.b.c;
for (i=0; i < 10000; i++) f.d(v);
webo.in
20 / 24
Элементарные операции
webo.in
21 / 24
Регулярные выражения
• Классический пример
var RegExp = '/script/gi';
items[i].nodeName.search(RegExp);
• в полтора раза медленнее, чем
/script/i.test(items[i].nodeName);
• или
/script/i.exec(items[i].nodeName);
webo.in
23 / 24
Перебор массива
• Классический пример
for (var j=0; j<10000; j++) {
for (var i=0; i<items.length; i++) {
var item = items[i];
}
}
• в 2-4 раза медленнее, чем
for (var j=0; j<10000; j++) {
var i = length - 1;
while (--i) {
var item = items[i];
}
}
webo.in
22 / 24
В следующей лекции
Практическое приложение
•
•
•
•
Инструменты для анализа
Онлайн-приложения
Оптимизация браузеров
Разбор полетов
webo.in
24 / 24
Download