-
Notifications
You must be signed in to change notification settings - Fork 47.6k
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
Bug: useTransition's pending boolean is triggered immediately, even if there's no suspension #18006
Comments
First guess: we're running into a CPU timeout there and flash the spinner. I wonder if we should adjust some heuristic so it doesn't happen that often though. |
My understanding is that I think it's fair to say that once we do show an inline spinner, it's bad to update the screen too fast after that. Even if we're ready. There's an undocumented I'll keep this open because there's probably more we could do there. E.g. keep the pending state around for longer by default, but prevent it from triggering if we didn't wait enough. There's probably better heuristics we could use. |
@gaearon looking at this again with fresh eyes, I definitely think there's a heuristic tweak needed. I've got a live demo up and running here: https://mylibrary.io/view?userId=573d1b97120426ef0078aa92 If you page up a few pages, and then page back down, you'll see cached results loading back up. On my MacBook on Chrome, the cached pages load as close to instantly as is probably possible, but I still get a flash of that spinner. Here's an even better example: https://mylibrary.io/view?page=2&subjects=583087fa8d9110f200d29f5d&userId=573d1b97120426ef0078aa92 Should be two total pages, page 2 should have 6 entries on it. Loading page 2 (cached) sometimes has the spinner not show, but it's always (again for me, essentially) instantaneous. |
Took another look at this — yea, I'm pretty sure this is because we're committing the initial https://codesandbox.io/s/busy-smoke-rjnrk?file=/src/index.js:358-563 const Spinner = ({ visible }) => (
<div
style={{
transition: visible ? "opacity 0.2s 0.2s linear" : "opacity 0s 0s linear",
opacity: visible ? 1 : 0
}}
>
loading...
</div>
);
Nope, that's the solution (if you want to keep it a spinner): #18006 (comment). |
Thanks @gaearon I appreciate you looking, and keeping the issue open. I'm relieved to hear you say it's a hack, which of course is more than good enough for something that's still pre-beta. But care-free spinner state was always one of the most loudly touted features of Suspense, so I really hope this gets buttoned up before it ships. Take care! |
@arackaf Your original Sandbox link is broken for me, but I copied the code to a new one and pointed it to the 18 beta release: Does it look good to you now? |
No, this still reproducible if you switch to My understanding is that it works as (currently) designed and is not a bug. Transitions don't only wait for suspending; they also unblock regular rendering. So the first commit always has I wonder what behavior would be preferred instead — not in this single case but in general. Let's assume the (existing) assumption that I suspect that the thing you're really looking for is more granular control and make it so that So far, my impression is that the CSS solution in #18006 (comment) is most flexible and I would recommend that for now. This issue is still on our list of things to look at. So we'll likely revisit this when/if we have better ideas around it. |
Damn. Silly oversight.
This matches my thinking (and I think what I said to Adam when we talked about this in person the other week). |
I've chatted a bit more to Sebastian about it today. There's a few things here. Our early communication over-emphasized spinners and that kind of became the default way of thinking about it. But in many designs they don't quite make sense. For transitions, in many cases it's reasonable to expect that For designs with spinners, the solution with CSS #18006 (comment) is the canonical solution. The great thing about it is that it works regardless of how long the work actually takes. If it takes too little, you simply won't notice the barely visible spinner. If it takes long enough, then you've had a chance to see it fully. You can also delay the transition itself with CSS. This lets you completely "skip" showing it for fast transitions. Additionally, since the CSS transition can be accelerated, you're not stealing time from CPU from the important work of actually finishing the render, as you would be with some JS-based solution. So we should be able to close this. There's definitely a need to document this pattern (and similar "how to think about X") though. But I think we have a conclusion on this issue. |
React version: 241c446
Steps To Reproduce
Link to code example:
The current behavior
Inline loading indicator usually shows on subsequent loads.
The expected behavior
It should only show on the first load of A
The text was updated successfully, but these errors were encountered: