Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Animation hiccups when an object is removed from the DOM #5400

Closed
meduzo opened this issue Dec 8, 2023 · 11 comments · Fixed by #5478
Closed

Animation hiccups when an object is removed from the DOM #5400

meduzo opened this issue Dec 8, 2023 · 11 comments · Fixed by #5478

Comments

@meduzo
Copy link

meduzo commented Dec 8, 2023

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

@dmarcos
Copy link
Member

dmarcos commented Dec 8, 2023

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
Copy link
Member

dmarcos commented Dec 8, 2023

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

@meduzo
Copy link
Author

meduzo commented Dec 9, 2023

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 meduzo closed this as completed Dec 9, 2023
@dmarcos dmarcos reopened this Dec 9, 2023
@dmarcos
Copy link
Member

dmarcos commented Dec 9, 2023

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

@mrxz
Copy link
Contributor

mrxz commented Dec 9, 2023

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)

@dmarcos
Copy link
Member

dmarcos commented Dec 9, 2023

@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
Copy link
Member

dmarcos commented Dec 10, 2023

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
Copy link
Member

dmarcos commented Dec 10, 2023

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

@mrxz
Copy link
Contributor

mrxz commented Dec 10, 2023

@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
Copy link
Contributor

mrxz commented Dec 17, 2023

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)

@dmarcos
Copy link
Member

dmarcos commented Dec 17, 2023

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants