gpt4 book ai didi

javascript - DOM Mutation Observers 是否比 DOM Mutation Events 慢?

转载 作者:可可西里 更新时间:2023-11-01 02:50:21 30 4
gpt4 key购买 nike

以下代码利用 DOM 突变事件 DOMNodeInserted检测 body 的存在元素并包裹它的 innerHTML放入 wrapper 中。

<!DOCTYPE html>
<html lang="en">
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script>
function DOMmanipulation() {
if (document.body) {
document.removeEventListener('DOMNodeInserted', DOMmanipulation);
// DOM manipulation start
document.body.innerHTML = '<div class="wrapper">' + document.body.innerHTML + '</div>';
// DOM manipulation end
}
}
document.addEventListener('DOMNodeInserted', DOMmanipulation);
</script>
</head>
<body>
<p>Lorem ipsum dolor sit amet.</p>
</body>
</html>

尽管包装成功,但有一个错误显示找不到节点。 This answer的一个问题解释说,这是因为当加载 jQuery 时,它添加了一个 div。元素进入 body 做一些测试,但未能删除 div元素,因为该元素已被包装到包装器中,因此它不再是 body 的子元素。

上面的实验告诉我们 DOMNodeInserted事件比 jQuery 的测试更快,因为 jQuery 的测试元素 ( div ) 在它可以被 jQuery 删除之前被包装。




现在下面的代码可以实现相同的操作,它使用了新引入的 DOM Mutation Observers。截至此时 (2012-07-11),它仅适用于 Chrome 18 及更高版本。

<!DOCTYPE html>
<html lang="en">
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script>
var observer = new WebKitMutationObserver(function() {
if (document.body) {
observer.disconnect();
// DOM manipulation start
document.body.innerHTML = '<div class="wrapper">' + document.body.innerHTML + '</div>';
// DOM manipulation end
}
});
observer.observe(document, { subtree: true, childList: true });
</script>
</head>
<body>
<p>Lorem ipsum dolor sit amet.</p>
</body>
</html>

这段代码没有产生任何错误。这意味着 jQuery 比 DOM Mutation Observers 更快,因此它能够在元素被包装到包装器之前删除它的测试元素 ( div )。




从以上两个实验中,我们发现在执行速度上:

  • DOM Mutation Events > jQuery 的测试
  • jQuery 的测试 > DOM Mutation Observers

这个结果能恰本地证明 DOM Mutation Observers 比 DOM Mutation Events 慢吗?

最佳答案

DOM Mutation Observers,并不打算比 DOM Mutation Events 更快。相反,它们旨在提高效率和安全性。

区别的基本要点是只要有变化,DOM 突变事件就会触发。例如,这段代码会创建一个回调循环,最终会使浏览器崩溃。

document.addEventListener('DOMNodeInserted', function() {
var newEl = document.createElement('div');
document.body.appendChild(newEl);
});

事实上,它们以这种方式被调用并且经常对浏览器产生重大影响,因为它迫使浏览器在重新计算样式、回流和重绘周期之间中断,或者更糟的是迫使浏览器重新计算样式、回流和在每次回调时重新绘制。可能执行的其他代码对 DOM 进行了进一步更改,这将继续被您的回调中断,这一事实进一步加剧了这个问题。

更重要的是,由于事件以与普通 DOM 事件相同的方式传播,您将开始听到您可能不关心或未在代码中考虑的元素的变化。因此,DOM Mutation Events 的整个机制很难快速管理。

DOM Mutation Observers 抵消了这些问题,顾名思义就是观察 DOM 的变化,并为您提供从变化开始时发生的所有变化的报告。这是一个更好的情况,因为它允许浏览器在有意义的时间通知您,例如当文档空闲并且所有其他可以进行进一步更改的 JavaScript 已完成执行时,或者在浏览器重新启动之前重新计算/重绘循环,因此它可以应用您所做的任何更改,而不必在不久之后重复该循环。

它还使您更容易管理,因为您可以扫描所有更改的元素以找到您要查找的内容,而不是像以前那样为您不关心的内容编写大量案例处理代码突变事件的情况。更重要的是,它只会调用一次,因此您不必担心任何进一步的更改都会影响元素,即它们不再处于变化状态,它们已经发生变化。

因此,在回答您的问题时,DOM Mutation Observers 速度较慢,因为它们会等待 jQuery 完成对 DOM 的操作,然后再通知您 jQuery 更改了什么。由于上面解释的原因和你的例子,证明它是更安全更有效的解决方案(你不再导致错误),你并不关心 jQuery 向 DOM 添加了一些东西,因为它会在不久之后删除它。使用 Observers,您会收到一份报告,详细说明添加和删除的 jQuery 元素。

但这仍然有点麻烦,因为您必须通过将元素与发生的所有更改进行匹配来弄清楚实际发生了什么。事实上,就您而言,没有发生任何事情(添加和删除相同的元素),因此 DOM 的结构实际上没有发生任何变化。为了帮助解决这个问题,有一个名为 MutationSummary 的小库:

http://code.google.com/p/mutation-summary/

这会计算更改的净效果,并且只会调用传递这些更改的回调。因此,在您的情况下,您的回调根本不会被调用,因为更改的净影响为零。

例如对于以下内容,您只会得到一次更改。主体样式更改为 left: 1000px。即使我以 1000 个增量更改它。更改的净效果只是其初始值与最终值之间的差异。

function moveBody() {
for (var i = 0; i < 1000; i++) document.body.style.left = i + 'px';
}
moveBody();

关于javascript - DOM Mutation Observers 是否比 DOM Mutation Events 慢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11425209/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com