Хорошие способы улучшить производительность селектора jQuery?

StackOverflow https://stackoverflow.com/questions/46214

Вопрос

Я ищу способ улучшить производительность селектора вызова jQuery.Конкретно такие вещи:

Является $("div.myclass") быстрее, чем $(".myclass")

Я думаю, что это возможно, но я не знаю, достаточно ли умен jQuery, чтобы сначала ограничить поиск по имени тега и т. д.У кого-нибудь есть идеи о том, как сформулировать строку селектора jQuery для обеспечения максимальной производительности?

Это было полезно?

Решение

Без сомнения фильтрация по имени тега выполняется намного быстрее чем фильтрация по имени класса.

Так будет до тех пор, пока все браузеры не реализуют getElementsByClassName изначально, как в случае с getElementsByTagName.

Другие советы

В некоторых случаях вы можете ускорить запрос, ограничив его контекст.Если у вас есть ссылка на элемент, вы можете передать ее в качестве второго аргумента, чтобы ограничить область запроса:

$(".myclass", a_DOM_element);

должно быть быстрее, чем

$(".myclass");

если у вас уже есть a_DOM_element и он значительно меньше всего документа.

Как сказал выше Рид, jQuery работает снизу вверх.Хотя

это значит $('#foo bar div') намного медленнее, чем $('bar div #foo')

Не в этом дело.Если у тебя есть #foo в любом случае вы бы ничего не помещали перед ним в селектор, поскольку идентификаторы должны быть уникальными.

Дело в том:

  • если вы выбираете что-либо из элемента с идентификатором, сначала выберите более поздний, а затем используйте .find, .children и т. д.: $('#foo').find('div')
  • ваша самая левая (первая) часть селектора может быть менее эффективным масштабированием до самой правой (последней) части, которая должен быть наиболее эффективным. Это означает, что если у вас нет удостоверения личности, убедитесь, что вы ищете $('div.common[slow*=Search] input.rare') скорее, чем $('div.rare input.common[name*=slowSearch]') - поскольку это не всегда применимо, обязательно задайте порядок селектора, разделив его соответствующим образом.

Чтобы полностью понять, что быстрее, вам нужно понять, как работает парсер CSS.

Селектор, который вы передаете, разбивается на распознаваемые части с помощью RegExp, а затем обрабатывается по частям.

Некоторые селекторы, такие как ID и TagName, используют собственную реализацию браузера, которая работает быстрее.В то время как другие, такие как класс и атрибуты, программируются отдельно и поэтому работают намного медленнее, требуя циклического перебора выбранных элементов и проверки каждого имени класса.

Итак, да, чтобы ответить на ваш вопрос:

$('tag.class') быстрее, чем просто $('.class').Почему?В первом случае jQuery использует собственную реализацию браузера, чтобы отфильтровать выбор только до тех элементов, которые вам нужны.Только тогда он запускает более медленную реализацию .class, фильтрующую то, что вы просили.

Во втором случае jQuery использует свой метод для фильтрации каждого элемента путем захвата класса.

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

Вот как можно повысить производительность ваших селекторов jQuery:

Я добавлю примечание, что в 99% веб-приложений, даже в тяжелых приложениях Ajax, производительность вашего приложения будет зависеть от скорости соединения и ответа веб-сервера, а не от JavaScript.Я не говорю, что вы должны писать намеренно медленный код или что вообще знать, какие вещи могут быть быстрее других, нехорошо.

Но мне интересно, пытаетесь ли вы решить проблему, которой на самом деле еще не существует, или даже оптимизируете что-то, что может изменять в ближайшем будущем (скажем, если больше людей начнут использовать браузер, поддерживающий getElementsByClassName() упомянутая ранее функция), из-за чего ваш оптимизированный код фактически работает медленнее.

Еще одним местом для поиска информации о производительности является страница анализа производительности селекторов Уго Видаля Тейшейры.

http://www.comComponenthouse.com/article-19

Это дает хорошее представление о скорости селектора по идентификатору, селектора по классу и имени тега с префиксом селектора.

Самые быстрые селекторы по id:$("#идентификатор")

Самый быстрый селектор по классу:$('тег.класс')

Таким образом, префикс по тегу помогал только при выборе по классу!

Я был в некоторых списках рассылки jQuery, и, судя по тому, что я там читал, они, скорее всего, фильтруют по имени тега, а затем по имени класса (или наоборот, если это было быстрее).Они одержимы скоростью и готовы использовать все, чтобы добиться хоть капельки производительности.

В любом случае я бы не стал слишком беспокоиться об этом, если только вы не запускаете этот селектор тысячи раз в секунду.

Если вы действительно обеспокоены, попробуйте провести сравнительный анализ и посмотреть, что быстрее.

Рассмотрите возможность использования библиотеки Sequentially Оливера Стила для вызова методов с течением времени, а не всех сразу.

http://osteele.com/sources/javascript/sequentially/

Метод «в конечном итоге» позволяет вызвать метод через определенный период времени с момента его первоначального вызова.Метод «последовательно» позволяет поставить в очередь несколько задач за определенный период времени.

Очень полезно!

А отличный совет из вопроса, который я задал:Использовать стандартные селекторы CSS где это возможно.Это позволяет jQuery использовать API селекторов.В соответствии с тесты, проведенные Джоном Ресигом, это приводит к почти естественной производительности селекторов.Такие функции, как :has() и :contains() необходимо избегать.

По результатам моего исследования поддержка API-интерфейса Selectors появилась в jQuery 1.2.7, Firefox 3.1, IE 8, Opera 10, Safari 3.1.

Если я не ошибаюсь, jQuery также является движком снизу вверх.Это значит $('#foo bar div') намного медленнее, чем $('bar div #foo').Например, $('#foo a') пройду через все a элементы на странице и посмотрите, есть ли у них предок #foo, что делает этот селектор чрезвычайно неэффективным.

Возможно, Резиг уже оптимизировал этот сценарий (я бы не удивился, если бы он это сделал — я думаю, что он это сделал в своем движке Sizzle, но я не уверен на 100%).

Я считаю, что выбор по идентификатору всегда быстрее:

$("#myform th").css("color","red");

должно быть быстрее, чем

$("th").css("color","red");

Однако мне интересно, насколько цепочка помогает при запуске с идентификатором?Это

$("#myform").find("th").css("color","red")
.end().find("td").css("color","blue");

быстрее, чем это?

$("#myform th").css("color","red");
$("#myform td").css("color","blue");
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top