React Suspense
react.christmas
react.christmas
I live in Australia, so there's a perceptible ~300ms delay for every action in react-like loaded later UIs that aren't hosted in Australia, which is most of the tools that I use. They feel clunky and broken, and the amount of times you miss-click because something pops in suddenly and moves the button you wanted down the page. I don't think it's the UI they think they've built.
I don't think it will ever be good enough to throw 20 requests and wait for everything to update, bounce the page around and at long last be intractable. I would rather receive a 2mb page right now, than a 200kb page that slowly grows to a 2mb page over the course of 20 components individually loading themselves.
Isn't the point that the 200kb is static code that can be served immediately, while the rest can't? Regardless of whether the remaining 1.8mb is built on the server or client, it still isn't available "right now"
This isn't really a problem unique to high latency either, if you have a patchy connection in transit or for some other reason, the UI will suffer.
That just sounds like bad front end coding. A good framework used properly would not have that issue.
Sure, but if it requires data from five different services and significant compute time, the initial request is going to be very slow. Users are more likely to bail out if they see nothing for a few seconds than if they immediately see a loading screen that lasts for a few seconds.
There's a nice middle ground.
In the app I work on very little is included at start up. It's literally just the components for the first screen you see. Then it pre-loads more components whenever the browser is idle based on what the user is likely to need. If the user does something that needs a component that isn't available yet it lazy loads it as usual.
If you only use lazy loading the user has to do something that needs a component and then wait until it's available. The strategy I use means there's an additional phase that utilises the time when the browser is idle, so it's much more likely everything is available before it's needed. It works well.
Freudian slip? Sounds about right though. The usability of huge portions of the web has deteriorated markedly in the last few years due to the over use of client-side frameworks.
Browsers should have an option to let you send click events to what was under the mouse 200ms before it was registered. But it would be a colossal PITA to implement.
import Component from 'component'
instead of lazy loading it ?
If you do server-side rendered pages, you still have to make the round-trip to get the next full HTML page. Switching to Vue or Svelte or JSPs isn't changing that.
An example, when loading a Jira ticket, you have to wait for the page to be sent to you, but it's not usable yet, then you wait for the individual areas of the page all to be sent to you, and as each one loads in at a different time the page goes all over the place and it's not clear when it's actually done and you can safely click stuff without your click target jumping away.
After that, interacting with a single part of the Jira ticket can still induce a load, but it's just the one, and it's expected and I can tell when it's done.
In most apps I've worked with, either (1) or (2) doesn't hold.
(1) The child is in control of the spinner:
<Parent>
<Child />
</Parent>
Child() {
if (!data) {
return <Spinner />
}
return <Data />
}
(2) The parent is in control of the data <Parent>
{ state.data
? <Child data={data} />
: <Spinner />
}
</Parent>
With Suspense, the child fetches its own data, but the parent is in control of the spinner: <Parent>
<Suspense fallback={<Spinner />}>
<Child />
</Suspense>
</Parent>
So the Child doesn't need to know the details of how the parent app wants to deal delays.Suspense then seems to make it easier to parallelize the data requests, and have a spinner at the lowest parent with a child waiting for data.
I think going all on on components is very easy to reason about. Same direction React Router went with component based routing making it very easy to for example have:
- logged in user portal - catch all errors and show a fallback UI - lazy load child components by routes with fallback loader UI - use a loader fallback potentially for data dependency too.
I mean, it's not perfect and I can see issues people are mentioning, but it feels pretty good to develop with.
Add to this styled components and everything is so component based it's really nice. One main paradigm for the whole front-end.
I don't think it's the best thing ever, but I've enjoyed the newer approaches when working with them.
This is because I feel like it's gonna be great for our apps and can't wait to try it on production though.
If you try to make nested components load at the same time consequences can be unpredictable, suspense lacks fine grained control so it is basically a convenient shortcut, same as react state mixins were at the time.
I'm inferring suspense is based on exceptions to interrupt unrenderable components, but it would be nice if the author told me.
They have been reluctant to discuss the details there, I guess it's because the details might change before the production release so they don't want to spell the actual inner workings out just yet.
They’ve already been banned from posting these to a site similar to HN.
Ant Design has also been a game changer for us.
Have you had any particular problems / downsides of using it?
And lastly have you considered ReasonML instead? That's the other thing I've been following closely but it never feels quite ready to start working with, for someone not well versed in FP that is.
And once you have those, you might as well have them implement the same “interface”, and now you’re cooking with functors ;)
No joke, it was error handling in successful promise resolves that made it an easy sell.
I adore Reason — I use it extensively myself, but as I also adore OCaml this shouldn’t be surprising. The downside is that it’s a harder sell for a mostly backend team; it can definitely be used to great effect today, but Typescript for all its downsides is easier to use right now.
Speaking of downsides: the major one with fp-ts (and io-ts) is some of the inscrutability of it’s more powerful abstractions for programmers who are not well versed in typed functional programming. But that’s okay: just don’t use them! You can get quite far with just the easy to understand concepts, and introduce things like EitherT or Task/IO and similar as the team becomes more confident with composing these data types!
That said, React Suspense looks like it's an improvement of a common pattern, simpler to write and understand. Perhaps it's achieved by pushing the complexity "down" into the library, instead of letting the user manage it every time.
My hope is that one day, all the lessons from React will be incorporated into browsers themselves, to clear the field for saner web development. Seeing how Web Components is going though, I'm not holding my breath..
Every other technology ever.
You'd still query and display your data in the same way. Suspense will just be a wrapper around the component displaying the data.
const Dogs = ({ onDogSelected }) => (
<Query query={GET_DOGS}>
{({ loading, error, data }) => {
if (loading) return 'Loading...';
if (error) return `Error! ${error.message}`;
return (
<select name="dog" onChange={onDogSelected}>
{data.dogs.map(dog => (
<option key={dog.id} value={dog.breed}>
{dog.breed}
</option>
))}
</select>
);
}}
</Query>
);Also several other topics following the same template: https://bekk.christmas
I love the different color patterns.