最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Web Animations API causing detached elements in Chrome DevTools Memory panel - Stack Overflow

programmeradmin0浏览0评论

Web Animations API causing detached elements in Chrome DevTools Memory panel

Issue

When I use the Web Animations API, I notice several detached objects in the Memory panel of Chrome DevTools. I’m not sure what’s causing this.

Summary

  • Objects retained by detached DOM nodes:
    • Detached <div class="line" style="display: none;">
    • Detached CSSStyleDeclaration
    • Detached DOMTokenList

Steps to Reproduce

  1. Open a page with the test case.
  2. Open DevTools → Memory, click Collect Garbage, then Take Heap Snapshot.
  3. First, run the test without animation (only with a timer):
    • Click Start in the test case,
    • Wait 1 second until the red element disappears,
    • Go to DevTools → Memory, click Garbage Collect, then Take Heap Snapshot.
    • Now we have two snapshots. Select Comparison mode and filter by "detached".
    • Expected: No detached elements.
  4. Delete snapshots and reboot page, repeat 1 and 2 items, run the test with animation:
    • In item 3 change the test mode to Animate and repeat the steps for create and comparise snapshots.
    • On two different computers, I consistently see detached elements appearing in the snapshots.

Code example:

const moveRight = [
    [{ transform: 'translateX(0)' }, { transform: 'translateX(100%)' }],
    {
        id: 'moveRight',
        duration: 1000,
        easing: 'linear',
        fill: 'forwards',
    },
];
const box = document.querySelector(".box")
let line = null
let animation = null

const cleanHandler = () => {
    line.style.display = "none"
    if (animation) {
        animation.removeEventListener('finish', cleanHandler);
        animation.cancel();
        animation = null;
    }
    let localLine = line;
    line = null
    setTimeout(() => {
        if (localLine) {
            localLine.remove()
            localLine = null;
        }
    })

};

document.querySelector("button.start").addEventListener("click", () => {
    if (line) return
    line = document.createElement("div")
    line.classList.add("line")
    const animated = document.getElementById("animate").checked
    box.appendChild(line)
    if (animated) {
        animation = line.animate(...moveRight)
        animation.addEventListener('finish', cleanHandler);
    } else {
        setTimeout(() => cleanHandler(), 1000)
    }
})
* {
    padding: 0;
    margin: 0;
    box-sizing: border-box;
}

.box {
    display: flex;
    overflow: hidden;
}


.line {
    background-color: red;
    flex: 1;
    height: 100px;
}
<button class="start">Start</button>
<input type="radio" name="radio" value="0" id="timeout" checked />
<label for="timeout">Timeout</label>
<input type="radio" name="radio" value="1" id="animate"/>
<label for="animate">Animate</label>
<div class="box">
</div>
发布评论

评论列表(0)

  1. 暂无评论