11 правил, следуя которым можно увеличить производительность скрипта, написанного с использованием jQuery.
Вот разметка, на основе которой будут примеры:
Это довольно вольный перевод вот этой статьи, которая попалась мне на глаза. Большинство из этих пунктов я знал и использовал, но нашел для себе еще немного нового.
Вот разметка, на основе которой будут примеры:
<div id="content"> <form method="post" action="/"> <h2>Traffic Light</h2> <ul id="traffic_light"> <li><input type="radio" class="on" name="light" value="red" /> Red</li> <li><input type="radio" class="off" name="light" value="yellow" /> Yellow</li> <li><input type="radio" class="off" name="light" value="green" /> Green</li> </ul> <input class="button" id="traffic_button" type="submit" value="Go" /> </form> </div>
- Искать элемент нужно по его аттрибуту id. Если у элемента нет id, то нужно указывать ближайший к нему элемент с id:
var active_light = $('#traffic_light .on');
Если мы ищем элемент через id, то это происходит быстро, потому что используется метод DOM getElementById.
- Использовать имя тега перед названием класса:
var active_light = $('#traffic_light input.on');
Тогда используется метод DOM getElementsByTagName и среди выбранных элементов ищется тот, у которого есть класс 'on'.
Выборка элементов по названию класса — одна из самых медленных выборок в jQuery.
Но никогда не надо ставить имя тега перед id:
var active_light = $('div#traffic_light');
Будут выбраны все элементы с тэгом 'div', а уже потом среди них будет найден элемент с нужным id.
- Кешируйте объекты jQuery:
Если вы используете объект больше чем один раз, вместо того, чтобы поворять несколько раз выборку елемента:
$('#traffic_light input.on).bind('click', function(){...});
$('#traffic_light input.on).css('border', '3px dashed yellow');
$('#traffic_light input.on).css('background-color', 'orange');
$('#traffic_light input.on).fadeIn('slow');
сохраните его в локальную переменную:
var $active_light = $('#traffic_light input.on');
$active_light.bind('click', function(){...});
$active_light.css('border', '3px dashed yellow');
$active_light.css('background-color', 'orange');
$active_light.fadeIn('slow');
'$' перед именем переменной можно ставить, чтобы показать что в ней храниться объект jQuery.
- Выстраивайте код в цепочки:
Поскольку большинство методов jQuery возвращают после выполнения объект jQuery, то предыдущий пример можно написать так:
var $active_light = $('#traffic_light input.on'); $active_light.bind('click', function(){return false;}) .css('border', '3px dashed yellow') .css('background-color', 'orange') .fadeIn('slow');
Это позволит нам сократить размер кода.
- Используйте подзапросы:
var $traffic_light = $('#traffic_light'), $active_light = $traffic_light.find('input.on'), $inactive_lights = $traffic_light.find('input.off');
Поскольку мы сохранили объект в переменной, то следующие выборки будут производиться только в сохраненном объекте, а не во всем дереве элементов.
- Минимизируйте работу с DOM-деревом
Поскольку манипуляции (удаление, перемещение и вставка новых элементов) с деревом DOM довольно медленные, то вместо того, чтобы вставлять каждый элемент в DOM:
var top_100_list = [...], $mylist = $('#mylist'); for (var i=0, l=top_100_list.length; i<l; i++) { $mylist.append('<li>' + top_100_list[i] + '</li>'); }
лучше сначала создать набор элементов в переменной, чтобы потом за один шаг вставить его в DOM:
var top_100_list = [...], $mylist = $('#mylist'), top_100_li = ""; for (var i=0, l=top_100_list.length; i<l; i++) { top_100_li += '<li>' + top_100_list[i] + '</li>'; } $mylist.html(top_100_li);
- Используйте делегирование событий:
Каждое событие «всплывает» в DOM дереве к элементам-предкам. Это можно использовать когда нескольким элементам на одно и то же событие нужно выполнить одинаковую функцию.
Вместо того, чтобы привязывать к каждому из этих элементов свое событие:
$('#entryform input).bind('focus', function(){ $(this).addClass('selected'); }).bind('blur', function(){ $(this).removeClass('selected'); });
можно привязать событие к элементу-родителю:
$('#entryform).bind('focus', function(e){ var cell = $(e.target); cell.addClass('selected'); }).bind('blur', function(e){ var cell = $(e.target); cell.removeClass('selected'); });
- Привязывать к странице только относящиеся к ней скрипты.
Обычно все складывается в один большой скрипт, который вставляется на все страницы сайта и выполняется на событие $(document).ready(). Но даже если функция не работает на данной конкретной странице, то все равно тратится время на поиск элементов, к которым привязана эта функция.
Поэтому можно разделить скрипт на несколько частей или же структирировать его сдедующим образом:
var mylib = { article_page : { init : function() { ... } }, traffic_light : { init : function() { ... } } }
а на странице, где мы хотим использовать функции, относящиеся, например, к traffic_light перед закрывающим </body> вставить:
<script type="text/javascript"> mylib.article.init(); </script> </body>
- Задержать загрузку до $(window).load
Чаще всего разработчики jQuery выполнение скрипта привязывают к событию $(document).ready(). Событие происходит в то время рендеринга страницы, когда объекты все еще загружаются. Иногда можно наблюдать что страница подвисает во вермя загрузки. Причиной этого могут быть именно функции, которые привязаны к $(document).ready().
Чтобы избавиться от этого, можно часть функций привязать к событию $(window).load(), которое происходит уже после того, как все содержимое страницы (включая содержимое iframe) уже загружено.
$(window).load(function(){ // функции jQuery, инициализируемые после загрузки страницы });
- Сжимать js код
Хотя это не и не имеет отношения именно к jQuery.
Это можно делать с помощью YUICompressor, Dojo ShrinkSafe, или же Google Closure Compiler.
- Изучайте jQuery
Читайте документацию, там можно найти много интересного.
Можно скачать cheatsheet по jQuery 1.3, чтобы функционал был в нужные моменты перед глазами.
Это довольно вольный перевод вот этой статьи, которая попалась мне на глаза. Большинство из этих пунктов я знал и использовал, но нашел для себе еще немного нового.