Оптимизация jQuery/лучшие практики

Ок седлать ковбоев, потому что это будет длинный. Я проводил утро, проходя через некоторые из моих старых кодов, и мне не интересно узнать о лучших практиках и оптимизации. Чтобы не дойти до субъективной полосы, я просто отправлю несколько примеров, с которыми, надеюсь, легко ответить на вопросы. Я попытаюсь привести примеры очень просто для облегчения ответа и уменьшить вероятность ошибок. Здесь мы идем:

1) Назначение vs jQuery Calls

Я понимаю, что при доступе к селекторам, как правило, лучше назначать селектор переменной, а не делать один и тот же вызов более одного раза - ex.

$('div#apples').hide();
$('div#apples').show();

против.

var oranges = $('div#oranges');
oranges.show();
oranges.hide();

Используется ли это же правило при ссылке на jQuery $(this)? Ex. Простой бит script, чтобы сделать некоторые данные в таблице доступными для кликов и настроить ссылку.

$('tr td').each( function() {
    var colNum = $(this).index();
    var rowNum = $(this).parent().index();
    $(this).wrap('<a href="example.com/hello.html?column=' + colNum + '&row=' + rowNum +'">'); 
})

против.

$('tr td').each( function() {
    var self = $(this);
    var colNum = self.index()
    var rowNum = self.parent().index()
    self.wrap('<a href="example.com/hello.html?column=' + colNum + '&row=' + rowNum +'">'); 
});

2) this vs $(this)

Хорошо, так что это следующий вопрос, о котором я давно задумывался, но я не могу найти никакой информации об этом. Пожалуйста, извините мое невежество. Когда имеет смысл называть ваниль js this в отличие от обернутого jQuery $(this)? Это мое понимание, которое -

$('button').click(function() {
  alert('Button clicked: ' + $(this).attr('id'));
});

Менее эффективен, чем доступ к атрибуту DOM объекта vanilla this, как показано ниже:

$('button').click(function() {
  alert('Button clicked: ' + this.id);
});

Я понимаю, что там происходит, я просто задаюсь вопросом, следует ли придерживаться правила, когда вы решаете, что использовать.

3) Лучше ли более определенно?

Это довольно просто, ВСЕГДА полезно быть более конкретным с нашими селекторами? Легко видеть, что $('.rowStripeClass') будет намного медленнее, чем $('#tableDiv.rowStripeClass'), но где мы рисуем линию? Является ли $('body div#tableDiv table tbody tr.rowStripeClass') еще быстрее? Любой вход будет оценен!

Если вы сделали это так, спасибо, что посмотрели! Если вы этого не сделали,: p

Ответ 1

Я постараюсь ответить на них максимально кратко:

  • Кэш, когда он используется часто, особенно в ситуации цикла, запуск того же кода для получения того же результата никогда не будет хорошим для производительности, кешируйте его.

  • Используйте this, когда вам нужен только элемент DOM и $(this), когда вам нужно методы jQuery (что не будет" t быть доступным в противном случае), ваш пример this.id vs $(this).attr("id") является идеальным, более распространенным примером:

    • Используйте this.checked вместо $(this).is(':checked')
    • Используйте $.data(this, 'thing') вместо $(this).data('thing')
    • Любой другой случай, когда создание объекта jQuery не является полезным в основном.
  • Отказ от выбора идентификатора является предпочтительным для производительности... насколько конкретно вам нужно быть? Это полностью зависит, короче говоря: будь то конкретным, каким вам нужно быть.

Ответ 2

1) Назначение vs jQuery Calls

Используется ли это же правило при ссылке на jQuery $(this)?

Да, абсолютно. Вызов функции $ создает новый объект jQuery, и с ним возникают связанные с этим накладные расходы. Несколько вызовов на $ с тем же селектором будут каждый раз создавать новый объект.

2) это vs $(this)

Я бы сказал, что важно знать, что разница важна, потому что время от времени становится критическим, что вы не обертываете свои объекты с помощью jQuery. В большинстве случаев вы не хотели бы делать преждевременную оптимизацию и просто поддерживать согласованность, всегда обертывайте их $(этим) и предпочтительно кэшируйте их в переменной. Однако рассмотрим этот крайний пример неупорядоченного списка <ul>, который содержит миллион элементов <li>:

$("#someList  li").each(function() {
    var id = $(this).attr('id');
});

Будет создано миллион новых объектов, которые повлекут за собой значительное снижение производительности, когда вы могли бы обойтись без создания каких-либо новых объектов вообще. Для атрибутов и свойств, которые являются совместимыми во всех браузерах, вы можете получить к ним доступ напрямую, не обернув его в jQuery. Однако, если это так, попробуйте ограничить его случаями, когда обрабатывается множество элементов.

3) Лучше ли более определенно?

Не всегда. В основном это зависит от браузеров, и снова не стоит вникать в микро-оптимизации, если вы точно не знаете, что что-то работает довольно медленно в вашем приложении. Например:

$("#someElement") vs $("#someElement", "#elementsContainer")

Может показаться, что, поскольку мы также предоставляем контекст при поиске элемента по id, второй запрос будет быстрее, но это наоборот. Первый запрос преобразуется в прямой вызов native getElementById(..), а второй - из-за селектора контекста.

Кроме того, некоторые браузеры могут предоставить интерфейс для доступа к элементам по имени класса с помощью getElementsByClassName, а jQuery может использовать его для этих браузеров для получения более быстрых результатов, и в этом случае для обеспечения более специфического селектора, например:

$("#someElement.theClass")

может на самом деле быть помехой, чем просто писать:

$(".theClass")

Ответ 3

Этот блог не слишком устарел, но он дает ответы на ваши вопросы, а также дает дополнительную информацию об ускорении вашего сайта при использовании jquery: http://www.artzstudio.com/2009/04/jquery-performance-rules/

Один из моих фаворитов - номер шесть, который утверждает, что ограничивает DOM-манипуляцию. Всегда полезно делать .append в цикле for, поскольку каждый раз, когда вы добавляете DOM, это дорогостоящая операция.

Ответ 4

По всем вопросам:

  • Кэширование объекта jQuery должно обеспечить лучшую производительность. Это позволит избежать поиска в DOM, что может замедляться при выполнении много раз. Вы можете воспользоваться цепочкой jQuery - иногда нет необходимости в локальной переменной.
  • То же самое происходит с $(this), когда this является элементом DOM. Несмотря на то, что это самый быстрый способ получить объект jQuery, он все же медленнее кэширования. Если элемент DOM ванили будет достаточным - тогда вообще не вызывайте jQuery. Пример с атрибутом id отличный - предпочитайте this.id чем $(this).attr('id), если вам не понадобится $(this)
  • Более конкретные селектора действительно уменьшат время поиска DOM. Однако есть действительно линия, которую нужно нарисовать - сделать селектора более конкретными, только если вы на 100% уверены, что это заметно улучшит производительность.

Ответ 5

В ситуациях только вы должны следить за циклами и событиями. Поскольку каждое действие, которое вы делаете в одном из них, будет выполняться на каждой итерации или на каждом событии.

  • Назначение vs jQuery Calls

    Ваш пример не самый лучший. Место, где вы должны сохранять ссылки на объекты jQuery, это те, которые используются в циклах или событиях, или которые являются результатами сложных запросов.

  • this vs $(this)

    Снова в критичных по производительности ситуациях лучше raw dom. Другой, который вы должны выбрать, который короче или более доступен для чтения. Сюрприз, удивите его не всегда jQuery.

  • Лучше ли более определенно?

    Существует больше типов, которые обычно сбиты с толку людьми. Один из них бесполезный, который: например, имя тега для селектора id tag#id, он будет медленнее простого id. Но существует другой тип, когда он будет иметь огромную выгоду. Теперь этот тип зависит от браузера, потому что современные будут жертвовать старыми, но это стоит компромисс. Это происходит, когда вы указываете tag для class tag.class. В IE 6-7 он будет значительно быстрее, чем простой .class, потому что sizzle может использовать функцию быстрого document.getElementsByTagName. Теперь другой тип, когда вы указываете слишком много предков. Это будет замедлить работу вниз в каждом браузере. Это происходит потому, что селектор выполняется справа налево. Правило, которое следует иметь в виду: всегда должно быть самым правым селектором как можно более конкретным.

Ответ 6

Статья в блоге 2013 года о лучших практиках jQuery

Обновленные ответы на ваш вопрос и даже больше о лучших практиках jQuery, применяемых в настоящее время, в этой статье посвящены интересным темам, которые действительно полезны и что вы можете прочитать.

Он касается вопросов, заданных здесь и даже больше: функция анимации, jQuery promises, лучшие способы импорта jQuery, событий jQuery и т.д. Надеюсь, что вам будет полезно!