Подтвердить что ты не робот

JQuery: добавление контекста в селектор намного быстрее, чем уточнение селектора?

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

$('li',$('#bar')).append('bla');

В два раза быстрее, чем:

$('#bar li').append('bla');

Это вообще правда?

4b9b3361

Ответ 1

добавление контекста в селектор много быстрее, чем очистка селектора

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

До и включая jQuery 1.2.6 механизм селектора работал в режиме "сверху вниз" (или "слева направо" ). Это означает, что оба примера будут работать примерно так:

var root = document.getElementById('bar');
return root.getElementsByTagName('li');

jQuery 1.3.x(т.е. Sizzle, в который вставляется jQuery) представил подход "снизу вверх" (или "справа налево" ) для запроса DOM. Итак, $('#bar li') теперь становится (примерно):

var results = [];
var elements = document.getElementsByTagName('li');
for(var i=0; i < elements.length; i++) {
    var element = elements[i];
    var parent = element.parentNode;
    while(parent) {
        if(parent.id == 'bar') {
            results.push(element)
            break;
        }
        parent = parent.parentNode;
    }
}
return results

Есть преимущества и недостатки обоих подходов. Вы нашли один из недостатков.

Изменить: только что узнал из это обсуждение, что Sizzle trunk теперь делает специальное исключение селекторов, где #id является первым. Он использует это как корневой контекст, немного ускоряя работу. Это должно уменьшаться, если не устранять различий в скорости, которые вы видите.