基于上下文的getElementById比本机getElementById慢1000倍。像sizzle这样的选择器引擎是否采用了更聪明的策略?

时间:2010-01-29 22:08:20

标签: javascript dom

有兴趣在dom之前构建html块之前将其插入dom中,我已经使用dynatrace进行了一些测试。我用bobince的方法: Is there any way to find an element in a documentFragment?

我发现它慢了近1000倍(在IE7中),这让我感到非常惊讶。

由于该功能非常基本,我想知道引擎使用的策略,如sizzle。

我想知道是否有更有效的方法来进行基于上下文的节点选择?

2 个答案:

答案 0 :(得分:1)

框架选择器引擎通常是右手优先评估的,所以我希望上下文ID选择器document.getElementById ID,然后通过加强{{{}来检查结果是否在上下文节点中1}}秒。这相当快,但它不适用于像这个例子那样的文档外DOM树。然后选择器引擎必须以极其缓慢的方式进行,或者不关心(例如,Sizzle不能与parentNode一起使用)。

对于实现Selectors-API(IE8,Firefox 3.5,Opera 10,Safari 3.1,Chrome 3)的浏览器,有一种更好的方法可以在我记忆中的片段中获取ID。您可以使用DocumentFragmentquerySelector作为上下文节点应用CSS选择器,因为API要求DocumentFragment实现DocumentFragment

NodeSelector

这不如alert(frag.querySelector('#myId')) 快,但它的加载比DOM版本更好。

不幸的是,大多数具有Selectors-API优化的框架在这​​种情况下或其他任何具有上下文节点的框架都不会使用它们,因为上下文节点的工作方式在getElementById [querySelector]到框架如何传统地实现它,使它们不兼容。

Selectors-API Level 2提出了“范围”方法,其行为类似于传统的框架选择器......在它可用之前还需要一段时间,但在此之前我们可能不会在现有框架中看到优化的上下文选择器。我认为这是一种耻辱,因为尽管使用上下文节点进行过滤而不是作用域的All方法并不是很好,但它仍然可以用于所有常见情况。

答案 1 :(得分:0)

如果您不介意暂时将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中已存在的ID且您想要搜索该ID的元素,这就可以正常运行。