javascript - 获取dom元素最快的方法是什么?

标签 javascript jquery dom

我正在对我的代码进行性能调整,并且惊讶地发现瓶颈不是插入 dom 节点,而是选择。

这很快:

var row = jquery(rowHTML).appendTo(oThis.parentTable);

但是随后获取“行”内的元素很慢:

var checkbox = jquery(".checkbox input", row);

我需要获取每一行中的复选框,以便我可以将事件处理程序附加到它。选择复选框的速度几乎是插入整个父行的 10 倍。

我在这里做错了什么?

最佳答案

DOM 操作使用 native 函数来执行简单的操作。浏览器 vendor 优化这些。您正在从 HTML 构建行。在内部,jQuery 使用 .innerHTML 构建集合,然后将其修补到浏览器的 super 快速解析器中。

选择比较慢,因为 JS 代码需要反复循环遍历 DOM。较新的浏览器具有 native 选择处理,可为基于选择器的 JS 提供显着的加速。随着时间的推移,这将不再是一个问题。

下面是相关查询 $(".checkbox input", row) 的分解方式:

  1. row.getElementsByTagName('*');
  2. for 循环返回的每个元素(行中的所有元素)并使用 /(\s|^)checkbox(\s|$) 测试 elements[i].className/.
  3. for 循环每个剩余的元素并收集 matched[i].getElementsByTagName('input');
  4. 独特的最终集合。

这与 jQuery 1.3 不同,因为它的引擎以相反的方式通过选择器,从获取所有输入元素开始,然后测试父元素。

请记住,JS 选择器引擎实现的 CSS 选择器规范比 CSS 实际可用的(或当前浏览器实现的)多得多。利用这一点以及对引擎的了解,我们可以通过几种不同的方式优化选择器:

如果您知道 .checkbox 是什么元素类型:

$("td.checkbox input", row);

先过滤类型然后再过滤那些匹配的类更快。这不适用于非常小的元素子集,但在实践中几乎从来没有出现过这种情况。

单类测试是常见测试中最慢的selectors people actually use .

更简单的选择:

$("input[type=checkbox]", row);

一个循环比两个循环快。这只会找到输入元素,然后直接按类型属性过滤它们。由于从不使用子/子元素,因此也可以跳过 unique(并且智能引擎会尝试这样做,因为 unique 很慢)。

更直接的选择器:

$("td:first.checkbox input", row);

如果更直接 (YMMV),更复杂的选择器实际上可能更快。

如果可能,将搜索上下文向上移动到表格级别:

我的意思是,与其循环遍历行,并在每一行中搜索复选框,不如将它们放在一边直到循环结束,然后一次选择所有行:

$("tr td:first.checkbox input", table);

这样做的目的是消除重复启动选择器引擎的开销,而是一次完成所有操作。这是为了完整性而不是我认为会返回大量加速的东西。

不要选择:

从位构建行,在进行时分配事件。

var row = $( '<tr></tr>' );
var cell = $( '<td class="checkbox"></td>' ).appendTo( row );
$( '<input type="checkbox" name="..."/>' ).appendTo( cell ).click(/* ... */);

由于 Ajax 或您无法控制的其他模板,这可能是不可能的。此外,速度可能不值得将您的代码变成这种困惑,但有时这可能是有意义的。

或者,如果这些方法都不适合您,或者返回的性能提升过大,可能是时候彻底重新考虑该方法了。您可以在树的更高层分配一个事件监听器并在那里获取事件,而不是每个元素的实例:

$('table').change(function(e){
  // you may want a faster check...
  if ( $(e.target).is('input[type=checkbox]') ) {
    // do some stuff ...
  }
});

通过这种方式,除非用户实际请求,否则您什么都不做。最快的。 :-)

关于javascript - 获取dom元素最快的方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/714375/

相关文章:

javascript - 为什么我不能将这些附加数据推送到我的数组中?

jquery - 当 aria-expanded 为 true 时,如何让屏幕阅读器正确说出 'button expanded'

dom - 隐藏的动画 GIF 是否仍然使用 CPU?

javascript - 如何将包含带引号的字符串的 javascript 对象从 node.js 传递到浏览器?

javascript - 类型错误 : Cannot read property 'click' of null

javascript - 正则表达式检查字符串中是否有任何单词不超过限制

javascript - jQuery:动画宽度/高度,但保持居中

javascript - 如何抓取埋在你抓取的元素中的元素?

javascript - 如何在 Firefox 中的纯 txt 文件上使用 innerHTML?

javascript - 如何修复基于 JSON 响应的 React 组件填充?