Контекстный метод getElementById в 1000 раз медленнее, чем собственный метод getElementById. Используют ли двигатели селектора, такие как Sizzle, более умную стратегию? - PullRequest
6 голосов
/ 30 января 2010

Заинтересовавшись созданием фрагментов html вне домена, прежде чем вставлять их в домен, я провел некоторое тестирование с использованием dynatrace. Я использовал метод Бобинса: Есть ли способ найти элемент в documentFragment?

Я обнаружил, что это почти в 1000 раз медленнее (в IE7), что меня очень удивило.

Поскольку эта функция довольно проста, мне было интересно узнать о стратегии, используемой такими двигателями, как sizzle.

Я хотел бы знать, есть ли более эффективные способы выбора узлов в контексте?

Ответы [ 2 ]

1 голос
/ 30 января 2010

Механизмы селектора Framework, как правило, оцениваются справа-на-первых, поэтому я ожидал, что контекстный селектор идентификатора document.getElementById ID, а затем проверил бы, были ли результаты в узле контекста, увеличивая parentNode s. , Это достаточно быстро, но оно не будет работать для DOM-деревьев вне документа, как в этом примере. Тогда двигатели селектора должны будут делать это крайне медленно, или не заботиться (например, Sizzle не работает с DocumentFragment).

Существует лучший способ получить идентификатор внутри фрагмента, который я запомнил с тех пор, для браузеров, реализующих Selectors-API (IE8, Firefox 3.5, Opera 10, Safari 3.1, Chrome 3) , Вы можете использовать querySelector, чтобы применить селектор CSS с DocumentFragment в качестве узла контекста, поскольку API требует DocumentFragment реализует NodeSelector:

alert(frag.querySelector('#myId'))

Это не так быстро, как getElementById, но загружается лучше, чем версия DOM.

К сожалению, большинство фреймворков, которые имеют оптимизацию Selectors-API, не будут использовать их в этом случае или любые другие с узлами контекста, потому что способ работы узла контекста отличается в querySelector [All] от того, как фреймворки традиционно реализовал это, делая их несовместимыми.

Selectors-API Level 2 предлагает «ограниченные» методы, которые ведут себя как традиционные селекторы фреймворка ... пройдет некоторое время, прежде чем его можно будет использовать, но мы, вероятно, не увидим оптимизированных контекстных селекторов в существующие рамки до тех пор. Я думаю, что это позор, так как хотя querySelector метод использования узла контекста для фильтрации, но не определения области видимости, не так хорош, он все еще в значительной степени применим для всех распространенных случаев.

0 голосов
/ 30 января 2010

Если вы не против временно вставить ваш documentFragment в DOM ...

function getElementFromFragById(frag, id) {
    var tempDiv = document.createElement("div");
    tempDiv.style.display = "none";
    tempDiv.appendChild(frag);
    document.body.appendChild(tempDiv);
    var elem = document.getElementById(id);
    document.body.removeChild(tempDiv);
    return document.getElementById(id) ? null : elem; //if the element still exists, we have a problem
}

Это работает надежно, если ваш documentFragment не содержит элементов с идентификатором, которые уже существуют в document, и вы хотите искать по этому идентификатору.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...