我试图修复这个基于微任务的去抖动器的内存泄漏:
function microtaskDebounce(fn) {
let scheduled = false;
let i = 0;
let elem = document.createElement('span');
// MutationObserver provides a mechanism for scheduling microtasks, which
// are scheduled *before* the next task. This gives us a way to debounce
// a function but ensure it's called *before* the next paint.
const observer = new MutationObserver(() => {
fn();
scheduled = false;
});
observer.observe(elem, { childList: true });
return () => {
if (!scheduled) {
scheduled = true;
elem.textContent = `${i}`;
i = i + 1; // don't use compund (+=) because it doesn't get optimized in V8
}
};
}
// usage example
const fn = microtaskDebounce(someFunction.bind(this));
for (let i = 0; i < 1000; i++) {
fn();
}
正如你所看到的,使用microtask debouncer,我用来检测重绘的DOM元素似乎泄漏并污染了内存。
我该如何解决?
供参考,这是我使用此功能的库: https://github.com/FezVrasta/popper.js/blob/v1-dev/src/popper/index.js#L132
将elem.textContent
替换为elem.setAttribute('x-index', i)
,并使用observer.observe(elem, { attributes: true });
进行观察以修复泄漏。
我仍然不明白为什么innerText
导致内存泄漏!
我在此CodePen中重现了这个问题: http://codepen.io/FezVrasta/pen/pRomWL
在debug mode
中打开它,让时间轴记录页面加载,你会在内存中看到数千个节点。