aframe icon indicating copy to clipboard operation
aframe copied to clipboard

Animation hiccups when an object is removed from the DOM

Open meduzo opened this issue 1 year ago • 11 comments
trafficstars

Description: Small animation hiccups happen whenever an entity is removed from the dom with "removeChild"

NOTE: Jumps from one frame to another are expected, however sometimes those jumps make the positions mismatch the expected position, see example.

gifer

  • A-Frame Version: 1.5.0
  • Platform / Device: All (more notable on Mobile VR like Quest headsets)
  • Reproducible Code Snippet or URL:
  • https://glitch.com/edit/#!/quirky-royal-branch

meduzo avatar Dec 08 '23 00:12 meduzo

Without investigating the particulars. In general you should avoid creating and destroying entities and reuse them to prevent unnecessary memory and other resource allocations. Can animate and reset the positions.

dmarcos avatar Dec 08 '23 22:12 dmarcos

A THREE.js example for reference https://glitch.com/edit/#!/sequoia-global-dove?path=index.html%3A49%3A46

dmarcos avatar Dec 08 '23 23:12 dmarcos

Thank you I assume this is not an a-frame issue, but a performance optimization issue then, I'll close it and dismiss it

meduzo avatar Dec 09 '23 02:12 meduzo

I think we should still investigate what's the root cause. no reason I can see why animations shouldn't be always smooth

dmarcos avatar Dec 09 '23 02:12 dmarcos

Thanks for the clear and concise glitch showing the issue @meduzo. I managed to find the root cause. The removal of the element happens while the scene is processing ticks, but the element's tick handlers are removed from the scene at that point as well. This can cause the scene to accidentally skip over some tick handlers, which for the animation component means it won't advance its animation for a frame.

I've created a PR that addresses this oversight: #5403 In the meantime as a crude workaround you can delay the removal by wrapping it in a setTimeout, like so:

setTimeout(() => {
    this.parentNode.removeChild(this);  
}, 0)

mrxz avatar Dec 09 '23 14:12 mrxz

@mrxz thanks! animation is janky even in the three example:

https://glitch.com/edit/#!/sequoia-global-dove?path=index.html%3A49%3A46

There might be additional issues

dmarcos avatar Dec 09 '23 20:12 dmarcos

With examples above notice that animation can be janky even when the application hits 60fps consistently. So wonder where is the jank coming from.

dmarcos avatar Dec 10 '23 00:12 dmarcos

Found this https://bugs.chromium.org/p/chromium/issues/detail?id=1164435 but also see stutter in Safari that it's not chromium. Tried on Macbook Air M1. Safari on iOS feels smoother

dmarcos avatar Dec 10 '23 00:12 dmarcos

@dmarcos I don't really see any jank in the three example. Only occasionally when it hits the bottom, but that's probably due to the setInterval not taking exactly 5000ms. Would be better to kick of the next animation cycle when the first one completes.

With Chrome I did notice that after a while the frame timings started to become inconsistent for brief periods (~1-2s at a time) resulting in slight judder, despite maintaining a steady 60fps. Wondering if it might be better to use the rAF timestamp to derive the delta instead of performance.now() as the former did maintain a virtually consistent 0.01667 throughout.

mrxz avatar Dec 10 '23 10:12 mrxz

Came across this Codepen: https://codepen.io/joliss/pen/wWKGeV/ This seems to indicate that using the rAF timestamp results in more consistent frame pacing compared to performance.now(). Effect is even more pronounced on Chrome since it actually provides sub-millisecond precision. It seems that the rAF timestamp reflects the "true" frame time, whereas measuring with performance.now() includes scheduling delays, which can be inconsistent between frames.

@dmarcos Could you test if you see the same issue with this Glitch (using rAF timestamp instead of performance.now()): https://glitch.com/edit/#!/towering-sequoia-scarer

If that resolves it, this might be worth using as the source for the delta in A-Frame. Though it warrants more testing (WebXR sessions, more devices/browsers, low fps)

mrxz avatar Dec 17 '23 16:12 mrxz

I think more or less the same. I'm not sure whether the issue is on our side or the browser updating the canvas. On chrome I usually have tons of tabs opened so might be a factor. To make sure is not our fault instead of visually it would be worth measuring frame time consistency. If we're hitting the numbers then it might be the browser.

dmarcos avatar Dec 17 '23 19:12 dmarcos