2009-09-11 2 views
5

У меня большие изменения в производительности, в зависимости от того, как я выражаю свои селекторы. Например, посмотрите на эти 2 селекторы, которые отбирают те же элементы:Производительность селектора jQuery

A) someTableRow.find("td.someColumnClass").find("span.editMode").find("input") 
B) someTableRow.find("td.someColumnClass span.editMode input") 

Я бы ожидать B), чтобы быть быстрее, так как есть только один звонок, но на самом деле я нахожу A) выполняет около В 8 раз быстрее. Я понятия не имею, почему у кого-то есть понимание? Спасибо

ответ

14

Предположив, что вы используете, по крайней мере JQuery 1,3 (т.е. с добавлением Шипение), производительность вы видите, это связано с изменением, в котором DOM является пройден. От here:

До и включая JQuery 1.2.6 двигатель селектор работал в «сверху вниз» (или «слева направо») образом. jQuery 1.3.x (т. е. Sizzle, в который встроен jQuery) вводит «снизу вверх» (или «справа налево») подход к запросу DOM.

В вашем втором примере ("td.someColumnClass span.editMode input"), Шипение эффективно делает это:

  1. получить все input элементов внутри someTableRow
  2. для каждого input найденных элемента, пересекает его предок дерево для span элементов с class="editMode". Удалить input элементов, которые не имеют этих предков
  3. для каждого найденного элемента span.editMode, перемещение его предка для td элементов с class="someColumnClass". Удалить input элементы, которые не имеют этих предков

В первом примере, однако, ваш являются отборочными каждый шаг явно с каждым вызовом find(), определяя контекст и перемещения вниз оттуда. Вы применяете подход «сверху вниз». Это эквивалентно переходу в контексте на каждом шаге, который generally considered a performance booster:

$('input', $('span.editMode', $('td.someColumnClass', someTableRow))) 
+0

Спасибо crescentfresh, имеет смысл. На самом деле мы просто перешли к 1.3.2 с 1.2.6, и я был смущен, почему некоторые ранее прилично быстрые селектора стали медленнее (большинство из них были быстрее). Вопрос - который быстрее, проходит в контексте в каждой точке или использует вызовы с цепочкой()? – JonoW

+0

Они эффективно эквивалентны. $ ('foo', 'bar') фактически перенаправляется в $ ('bar'). find ('foo') в животе jQuery. Я полагаю, что вызов find() явно сохраняет пару циклов процессора, но нечего мигать. Сделайте то, что наиболее читаемо для вашей команды. Я нахожу, что нахожу очень читаемым;) –

+0

Прохладный, я чувствую, что find() более интуитивно понятен для меня, поэтому будет использовать это – JonoW

1

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

2

Поскольку вы уменьшаете контекст поиска.

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

В случае, если A, может быстро решить игнорировать что-либо, что не является «td.someColumnClass», тогда он может принять это подмножество DOM и игнорировать все, что не находится в «span.editMode». Таким образом, он имеет гораздо меньший набор элементов для поиска, чтобы найти «входные данные» сейчас.

+1

Как он может «быстро решить игнорировать ...», не пройдя через всех детей DOM от someTableRow? Оба они проверяют один и тот же полный набор элементов children, один ищет td с someColumnClass, затем анализирует этот список для промежутков с editMode, а затем анализирует этот список для ввода. Другой ищет все три критерия при одном и том же поиске исходного списка. – billjamesdev

+0

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

-1

Там это действительно интересная статья об исполнении селекторного здесь: http://blogs.atlassian.com/developer/2009/08/jquery_bondage.html

В ней автор показывает «привязку» расширение JQuery, который показывает, сколько раз вычисляется функция.

+1

Ответчик ссылается на производительность 'find()', а не 'bind()'. –

1

То, как JQuery обрабатывает selctors, немного отличается от CSS в моем опыте.

Уменьшение контекста поиска - это ключ, как указал Джош.

Я нахожу с помощью двух селекторов параметров действительно быстро

Как это сравнить скорость мудрое?

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

var columnClasses = $('.someColumnClass'); 
var tableCell = $('td', columnclasses); 
var editMode = $('.editmode', tableCell); 
var spanInside = $('span', editMode); 
var inputFinally = $('input', spanInside); 

Kindness,

Dan

1

Я сделал некоторые исследования на JQuery выбора производительности сам. Большая проблема - это поиск по имени класса в Internet Explorer. IE не поддерживает getElementsByClassName - поэтому jQuery и другие фреймворки «переопределяют» его в JavaScript путем итерации через все элементы DOM. Оставьте комментарий следующий анализируемый блог О jQuery Selector Performance

Смежные вопросы