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

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

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

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

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

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


person bart    schedule 16.03.2009    source источник


Ответы (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 теперь делает специальное исключение для селекторов, где #id стоит первым. Он использует это как корневой контекст, что немного ускоряет работу. Это должно уменьшить, если не устранить разницу в скорости, которую вы наблюдаете.

person Crescent Fresh    schedule 16.03.2009