对于已删除的元素,我应该调用ResizeObserver.unobserve吗



当一些观察到的元素从DOM中删除时,我应该为该元素调用.unobserve以防止内存泄漏吗;无人自动观察";?

const ro = new ResizeObserver((entries) => { console.log(entries); });
const el = document.getElementById('foo');
ro.observe(el);
// ... some time later
el.remove();
ro.unobserve(el); // <-- is this needed, or does it happen automatically behind the scenes?

为什么我要问:我正在实现一个React组件,它可以观察许多子组件,正确地清理未安装组件的观察者将涉及非琐碎的代码,如果它实际上是不必要的,我希望避免这些代码。

根据csswg drafts存储库中的问题,如果您从DOM中删除该元素并从JS中删除任何引用,Chrome将自动取消对该元素的观测。

let el = document.querySelector("#id");
let ro = new ResizeObserver();
ro.observe(el);
setTimeout(_ => {
el.remove();
el = null;
}

如果没有JS引用,当前Chrome代码会隐式取消服务元素。这不是规范所捕获的。

但问题仍然悬而未决。。。

是的,您应该使用unobserve()diconnect()。对于我自己的项目,当我不使用它时,我的应用程序中出现了内存泄漏

我还发现.unobserve()的使用令人困惑。但是,如果提供拆卸。。一般来说,使用它可能是一种很好的做法。在开发代码时添加它肯定比在忘记为什么要做某事后在未来更新更容易。

我也在使用React,但我正在使用useEffect挂钩来清理它。

我不得不做一些尝试和错误来找出有效的方法,而且最初也错过了ResizeObserver的.disconnect()电话。

所以目前对我有效的是:

const [height, setHeight] = useState(null);
useEffect(() => {
const heightObserver = new ResizeObserver((entries) => {
setHeight(entries[0].contentRect['height']);
});
heightObserver.observe(el);
return () => {
if(el){
heightObserver.unobserve(el);
} else {
heightObserver.disconnect();
}
}
},[]);

在我的试错中,以下内容对我不起作用。

这将导致"el不存在"错误:

...
return () => {
heightObserver.unobserve(el);
}
...

我可以测试一下,但这会导致内存泄漏:

...
return () => {
if(el){
heightObserver.unobserve(el);
}
}
...

然后我发现了.disconnect(),虽然没有浏览器问题,但不幸的是,所需的行为停止了,只有:

...
return () => {
heightObserver.disconnect();
}
...

所以这就是我的过程,希望它能帮助到别人。我仍然觉得可能有更好的方法来做我正在做的事情,但从我所能看出的情况来看,这是有效的。

最新更新