Replies: 2 comments 1 reply
-
Looking at the code some more: if (state === true) {
roots.forEach((root) => {
const state = root.containerInfo.__state
state.current.frames = state.current.ready ? state.current.frames + frames : frames
})
} else if (state && state.current) {
if (state.current.vr) return
state.current.frames = state.current.ready ? state.current.frames + frames : frames
} I would like to have a better understanding of the function of the I've patched my code by changing this code to: |
Beta Was this translation helpful? Give feedback.
-
invalidation doesnt render, it is a simple count, and if it's > 0 it will render once per frame, never more than once. it can double render (two frames, one after the other) to avoid some browser nonsense like minimize/maximize being a event late - so invalidate is not deterministic, but this is a dead-end, that's not the problem you're facing. in your screenshot there is no indication of three rendering more than once, this is all react doing some intense churn and it's most likely caused by a bug in your app, not r3f. it looks like setstate in a loop to me or inside a event, which would not be good. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
I found some interesting behavior.
When I have the devtools open, frame invalidation based on mouse movements (with orbitcontrols) seems to stack. For example, I have a mouse that toggles profiles, and one is set to 125Hz polling rate, and one at 1000Hz polling rate. This means that this will be the frequency with which the OS will feed input events to an application.
I noticed that something was weird because when my application changes state that affects the 3d canvas, it will render frames for a few seconds even when frame invalidation is turned on. I thought this was odd so I was tinkering a bit. I found that when interacting with the mouse to move the camera, after releasing the mouse, for some time it will continue to render out frames.
I realized that when I switch to an input device that has a lower 125Hz polling rate, since my monitor's refresh rate is close (120Hz), it does not exhibit this behavior! And if I change my monitor to 60Hz, it will do it again, but reduced compared to before. Starting to make sense... So anyway, after extensive testing, I did determine that indeed invalidate runs at mouse polling frequency, only when the devtools are open or when recording with the performance tab in chrome, it does not happen when the devtools are closed, or under firefox.
I have seen https://spectrum.chat/react-three-fiber/general/clarification-about-invalidateframeloop-invalidate~1c0c4a70-4df1-4eaf-b5db-4323e7b1b2cd in which it's made clear that the intent behind invalidate is such that it's marking it dirty so rendering the next frame is performed.
For whatever reason, it seems that this is
This is a screenshot from my app where I have added some performance.mark instrumentation in
node_modules/react-three-fiber/web.js
around the invalidate call, actually, although that isnt directly visible in the screenshot there, you can see where my mouse hovers (sorry no mouse cursor is shown but the popup is shown), this entire stack is react updating and it seems to be doing a whole lot of invalidate calls in there, and these actually do stack up, resulting in several seconds worth (hundreds and hundreds) of frames being rendered after the react operation is done. I'd like to do something about this since those invalidates are being called all while rendering is blocked so it really only needs to render either zero times or once after doing all the work, not hundreds of times.I also have invalidate (in react three fiber) instrumented with this log:
which prints the amount of stacked frames!
Here is a video showing the logs with different rates of input:
2021-02-02.01-57-29-3.mp4
you can sorta see when it stops rendering because i did crank up the noise postprocess filter. Though, the compression I had to do to get it under 10MB sort of destroys that. Anyway you can see whats going on with the log output on the console.
The point is not that it's a bug that gaming low latency mice cause extra stacked renders when the events don't get coalesced, although it's not clear yet why coalescing fails to occur when the devtools are open in Chrome, it's normal that it happens. Here's some info on what the coalescing is about https://developers.google.com/web/updates/2017/06/aligning-input-events. The problem is with the queued number of frames continuing to render continuing to increment, by default, when the behavior should really just be marking it as dirty. I wish I was more familiar with what reasons exist for actually counting the number of frames to stack, then I could try to improve the code.
Beta Was this translation helpful? Give feedback.
All reactions