javascript - querySelectorAll vs NodeIterator vs TreeWalker - 最快的纯 JS 平面 DOM 迭代器

标签 javascript html performance dom traversal

我想将 DOM 树扁平化为 Array。 结果应包括根作为第一个条目。 首选纯 JS 解决方案。 实现这一目标的最快方法是什么?

HTML结构示例:

<div class="tested-root">
    <span></span>
    <span></span>
    <div>
        <span></span>
        <span></span>
    </div>
    <div>
        <span></span>
        <span></span>
    </div>
</div>

预期的输出是: [div.tested-root, span, span, div, span, span, div, span, span] 或类似的(这个是DFS,但为了这个问题并不重要) .

从以下三种方法中哪个最快:

  • querySelectorAll
  • 节点迭代器
  • 树行者

最佳答案

我最近才来尝试其他一些。 下面是从最慢到最快的结果,同时指定一个比最快的慢。

Chrome based results. Safari shows roughly the same numbers. Firefox has issues with that perf app and was not verified.

方法 1(不移位)~81% 慢

const list = Array.from(root.querySelectorAll('*'));
list.unshift(root);

方法 2(传播)~77% 慢

const list = [root, ...root.querySelectorAll('*')];

方法 3(NodeIterator)~32% 慢

const list = [];
const ni = document.createNodeIterator(root, NodeFilter.SHOW_ELEMENT);
let next;
while (next = ni.nextNode()) {
    list.push(next);
}

方法 4(TreeWalker)最快

const list = [root];
const tw = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT);
let next;
while (next = tw.nextNode()) {
    list.push(next);
}

奖励(空根检查)慢约 1%(空根快约 98%)

const list = [root];
if (root.childElementCount) {
    const tw = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT);
    let next;
    while (next = tw.nextNode()) {
        list.push(next);
    }
}

观察与结论

  • 数组操作,如果/当考虑时,表明传播 (...) 运算符方式比 unshift 方法更快
  • 主要性能提升来自使用 native 迭代器,TreeWalker 是迄今为止最快的
  • 几乎总是实现这种特殊的加速奖励是合理的,对于嵌套结构,影响可以忽略不计,但对于一棵空树,它的运行速度 两倍 快<

可以找到基准测试 here .

关于javascript - querySelectorAll vs NodeIterator vs TreeWalker - 最快的纯 JS 平面 DOM 迭代器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64551229/

相关文章:

javascript - 在 Javascript 中从 JSON 获取多个无组织的值

MySQL 5.1 在存在索引时使用文件排序事件

java - 使用 Java 8 Stream(列表中的大量数据)时的性能问题

performance - Linq To Sql 与 Entity Framework 性能

javascript - 如何迭代 .innerHTML 中字符串的每个字符(for 循环)?

需要 JavaScript 来填充内容和页脚之间的剩余高度空间

javascript - 我可以更改 HTML 元素的类型吗?

javascript - jquery 替换 HTML div 值

javascript - 使用 :hover to modify the css of another class?

javascript - 使用ajax在后台上传照片