Пишем качественный код на jQuery
На данный момент существует достаточное количество статей, в которых обсуждается производительность библиотеки jQuery и JavaScript. Однако в этой статье я хотел бы подвести черту и собрать воедино основной набор советов по улучшению производительности и качества кода, который вы пишете, а также поделиться несколькими ценными наблюдениями из моего собственного опыта. Качественный код – это прежде всего быстрые приложения и сайты без лишнего мусора. В конце концов, быстрая отрисовка страниц и улучшенное реагирование принесут вашим пользователям более позитивный опыт взаимодействия.
Важно помнить несколько ключевых моментов. Во-первых, jQuery — это и есть JavaScript. Что, в свою очередь, значит, что нам нужно использовать одни и те же общие правила при написании кода, гайдлайны стиля и передовые практики, как для самого языка, так и для работы с библиотекой, на котором она написана.
Во-вторых, я настойчиво рекомендую всем новичкам, которые только начали осваиваться с JavaScript, перед тем, как связываться с jQuery, прочитать следующие статьи: о передовых JavaScript-практиках для начинающих, и о том, как писать качественный JavaScript-код.
Когда вы будете готовы использовать jQuery, я настоятельно советую вам придерживаться нижеследующих принципов:
Кэшируйте выборку в переменных
Выборка элементов в дереве DOM иногда может быть очень ресурсоёмкой операцией, поэтому старайтесь кэшировать выбранные элементы в переменных, если вы собираетесь использовать их повторно в коде.
// плохо
h = $('#element').height();
$('#element').css('height',h-20);
// хорошо
$element = $('#element');
h = $element.height();
$element.css('height',h-20);
Не используйте глобальные переменные
Для jQuery, как и для JavaScript, лучше всего делать так, чтобы переменные были замкнуты внутри функций, в которых они используются.
// плохо
$element = $('#element');
h = $element.height();
$element.css('height',h-20);
// хорошо
var $element = $('#element');
var h = $element.height();
$element.css('height',h-20);
Используйте венгерскую нотацию
Если говорить простыми словами, венгерская нотация1 в jQuery — это когда в начале переменной стоит символ доллара, и вам легко сразу понять, что эта переменная содержит jQuery-объект.
// плохо
var first = $('#first');
var second = $('#second');
var value = $first.val();
// хорошо - перед объектами, которые управляются jQuery, мы ставим символ $
var $first = $('#first');
var $second = $('#second'),
var value = $first.val();
Используйте цепочки переменных (паттерн одного ‘var’)
Вместо того чтобы писать директиву var для каждой объявляемой переменной, можно объединить несколько переменных в одну var-цепочку. Я советую ставить все переменные, не имеющие на текущий момент конкретного значения, в конец цепочки.
var
$first = $('#first'),
$second = $('#second'),
value = $first.val(),
k = 3,
cookiestring = 'SOMECOOKIESPLEASE',
i,
j,
myArray = {};
Используйте ‘On’
Последние версии библиотеки jQuery привнесли изменения в функции типа
click()
— теперь это сокращение от on('click')
. В более ранних версиях
click()
являлся сокращением от bind()
. Начиная с версии jQuery 1.7
предпочтительный метод для привязки обработчиков событий — on()
. Для
единообразия гораздо проще использовать on()
везде в подобных случаях.
// плохо
$first.click(function(){
$first.css('border','1px solid red');
$first.css('color','blue');
});
$first.hover(function(){
$first.css('border','1px solid red');
})
// лучше
$first.on('click',function(){
$first.css('border','1px solid red');
$first.css('color','blue');
})
$first.on('hover',function(){
$first.css('border','1px solid red');
})
Концентрированный JavaScript
В общем, там, где есть для этого возможность, лучше совмещать несколько функций в одну.
// плохо
$first.click(function(){
$first.css('border','1px solid red');
$first.css('color','blue');
});
// лучше
$first.on('click',function(){
$first.css({
'border':'1px solid red',
'color':'blue'
});
});
Используйте цепочки
Библиотека jQuery позволяет вам очень просто связывать методы в цепочки. Пользуйтесь этим!
// плохо
$second.html(value);
$second.on('click',function(){
alert('hello everybody');
});
$second.fadeIn('slow');
$second.animate({height:'120px'},500);
// лучше
$second.html(value);
$second.on('click',function(){
alert('hello everybody');
}).fadeIn('slow').animate({height:'120px'},500);
Оставляйте код читаемым
Но когда вы пишете компактный код и используете цепочки, код, вполне возможно, может стать нечитаемым. Используйте отступы и переносы строк, чтобы он выглядел красиво.
// плохо
$second.html(value);
$second.on('click',function(){
alert('всем привет');
}).fadeIn('slow').animate({height:'120px'},500);
// лучше
$second.html(value);
$second
.on('click',function(){ alert('всем привет');})
.fadeIn('slow')
.animate({height:'120px'},500);
Используйте сокращенные вычисления для логических выражений
Сокращенное вычисление означает, что выражения оцениваются слева направо с
использованием операторов &&
(логическое и) и ||
(логическое или).
// плохо
function initVar($myVar) {
if(!$myVar) {
$myVar = $('#selector');
}
}
// лучше
function initVar($myVar) {
$myVar = $myVar || $('#selector');
}
Сокращайте!
Один из способов сделать код более компактным — воспользоваться сокращениями.
// плохо
if(collection.length > 0){..}
// лучше
if(collection.length){..}
Отделяйте элементы, когда нужно провести с ними ресурсоёмкие операции
Если вы собираетесь провести ряд ресурсоёмких операций над элементом DOM, рекомендуется отделить его от документа, а потом добавить снова.
// плохо
var
$container = $("#container"),
$containerLi = $("#container li"),
$element = null;
$element = $containerLi.first();
//... много сложных манипуляций
// лучше
var
$container = $("#container"),
$containerLi = $container.find("li"),
$element = null;
$element = $containerLi.first().detach();
//... много сложных манипуляций
$container.append($element);
Знайте особенности
Если вы используете jQuery-методы, с которыми у вас не так много опыта работы, не поленитесь предварительно прочесть документацию: вполне возможно, для вашей задачи есть заранее продуманный или более оптимальный вариант решения.
// плохо
$('#id').data(key,value);
// лучше (быстрее)
$.data('#id',key,value);
Кэшируйте родительские элементы для подзапросов
Как я говорил выше, поиск по DOM — дорогостоящая в плане ресурсов операция. Зачастую лучше кэшировать родительские элементы, а потом использовать уже закэшированные элементы для выбора дочерних.
// плохо
var
$container = $('#container'),
$containerLi = $('#container li'),
$containerLiSpan = $('#container li span');
// лучше (и быстрее)
var
$container = $('#container '),
$containerLi = $container.find('li'),
$containerLiSpan= $containerLi.find('span');
Не используйте универсальный селектор
Универсальный селектор в совокупности с другими селекторами — это очень медленная выборка.
// плохо
$('.container > *');
// лучше
$('.container').children();
Вместо подразумеваемого универсального селектора, пишите конкретные селекторы
Если вы не указываете никакого селектора, по умолчанию подставляется
универсальный селектор (*
).
// плохо
$('.someclass :radio');
// лучше
$('.someclass input:radio');
Оптимизируйте селекторы
Например, если вы используете id — это уже достаточно специфический запрос, поэтому не нужно добавлять дополнительную специфичность в выборку через добавление других селекторов.
// плохо
$('div#myid');
$('div#footer a.myLink');
// лучше
$('#myid');
$('#footer .myLink');
Не используйте в запросе путь из нескольких id
Еще раз повторюсь, если вы используете id правильно, то одного id вполне достаточно, и дополнительная специфичность в запросе из нескольких вложенных id селекторов не требуется.
// плохо
$('#outer #inner');
// лучше
$('#inner');
Старайтесь использовать последнюю версию библиотеки
Чаще всего новая версия является лучшей по сравнению с предыдущей. Обычно она легче или, например, быстрее. Однако не стоит забывать об обратной совместимости и поддержки кода. Например, версия библиотеки jQuery 2.0 не поддерживает версии браузера Internet Explorer 6, 7 и 8.
Не используйте устаревшие методы
Всегда смотрите на список устаревших методов в каждой новой версии и старайтесь их не использовать в вашем коде.
// плохо - метод live является устаревшим
$('#stuff').live('click', function() {
console.log('ура!');
});
// лучше
$('#stuff').on('click', function() {
console.log('ура!');
});
Загружайте jQuery с CDN
Наиболее быстрый способ передать пользователю скрипт с ближайшего к нему
сервера — использовать технологию CDN от Google.
Чтобы использовать CDN Google, используйте в коде следующий адрес:
http://code.jquery.com/jquery-latest.min.js
Старайтесь совмещать jQuery и нативный JavaScript
Как я говорил выше, jQuery — это не что иное, как JavaScript, а, значит, на jQuery мы всего лишь делаем те же самые вещи, которые могли бы делать и на встроенном в браузер JavaScript. Конечно же, когда вы пишете на нативном («ванильном») JavaScript, это зачастую приводит к длинным файлам с нечитаемым кодом, который сложно поддерживать. Однако, это также означает и то, что ваш код будет исполняться быстрее. Помните, что нет такого js-фреймворка, который был бы легче в исполнении для браузера, чем операции на нативном JavaScript.
(Кликните на картинку и проверьте)
Из-за разницы в производительности между встроенным в браузер JavaScript и jQuery я настоятельно рекомендую использовать их вместе (но делать это со всей ответственностью). И, по возможности, используйте как можно чаще нативные аналоги для функций jQuery.
Напутствие напоследок
Напоследок, я рекомендую вам прочитать эту статью об увеличении производительности jQuery. В ней так же содержится ряд других замечательных советов по оптимизации кода, которые, несомненно, будут вам интересны, если вы хотите поглубже разобраться в этой теме.
Не забывайте также, что использование jQuery – это выбор, а не требование. Подумайте, зачем вы вообще используете jQuery. Для преобразований DOM? AJAX? Шаблонов? CSS-анимаций? Как движок селекторов? Возможно, для ваших задач имеет смысл использовать микрофреймворки на JavaScript или какую нибудь кастомную сборку jQuery, которая будет четко отвечать требованиям вашего проекта.
Примечания
1.Венге́рская нота́ция в программировании — соглашение об именовании переменных, констант и прочих идентификаторов в коде программ. Своё название венгерская нотация получила благодаря программисту компании Microsoft венгерского происхождения Чарльзу Симони, предложившему её ещё во времена разработки первых версий MS-DOS. Эта система стала внутренним стандартом Майкрософт. Подробнее о ней вы можете прочесть в Википедии.