
React Concurrent Mode - gmaster1440
https://reactjs.org/docs/concurrent-mode-intro.html
======
danabramov
While this page went to the top, I see a lot of comments that show people
haven’t seen the other pages.

I know it’s a lot to ask. But this really is a different programming model. It
takes some time to see what it allows.

I spent the last 48 hours documenting it. Here are the most important two
pages:

1\. [https://reactjs.org/docs/concurrent-mode-
suspense.html](https://reactjs.org/docs/concurrent-mode-suspense.html)

2\. [https://reactjs.org/docs/concurrent-mode-
patterns.html](https://reactjs.org/docs/concurrent-mode-patterns.html) (
_especially_ this one!)

It would mean a lot to me if you could go through both of them (including the
examples) before forming a final opinion. Thank you.

~~~
andrewstuart
Thanks to Dan and the React team - great work as always.

The most useful thing to provide with this would be a small self contained
example of the absolute core of all web programming - a form that gets data,
submits it to the back end, and then displays a list of records. Nothing more.
Super simple. All web development knowledge derives from this start point -
for me anyway.

This is what underpins all web development and when I come into a new approach
like this I always aim to implement that basic display/submit/list form
workflow.

It would be SO helpful if that existed as a small standlone application.

The profile stuff is in the right direction but not it.

When there is not a basic example of that exact workflow then the cognitive
load instantly skyrockets because I now need to work out how to do that and
even then I don't know if I got it right because it's my guess using a
technology I do not understand. So much better for the technology designers to
show how to do the core of all development "the new way". Ideally with a
standard form and not graphql.

~~~
jpochtar
Rails is probably a better fit for your needs. If you're primarily concerned
with sending forms to and showing data from a server, React isn't going to
give you much.

React is great for Figma, Dropbox Paper, Coda, and Pagedraw: apps that are
basically entirely local, and may or may not happen to be syncing with a
server in the background.

CRUD is a special case of app, and the modern HTML/CSS/JS browser is pretty
well tailored to handle all the needs for the client side of one. Maybe
sprinkle in some Turbolinks [1] if you want some fancier page transitions.

It'll take time before someone makes a good CRUD framework on top of React.
Until then, Rails is a great CRUD framework, and isn't missing much I'd expect
to see React solve.

[1]
[https://github.com/turbolinks/turbolinks](https://github.com/turbolinks/turbolinks)

~~~
egeozcan
If you're not living in a first world country (or living in Germany lol), you
usually don't have a stable internet connection. I've developed a lot of CRUD
apps that are core to many businesses on field and without ServiceWorkers (or
the manifest based appcache before) and client side databases that are better
suited to use from SPAs, I'd rarely have success in any of those projects.

You don't really need a framework for this. Forms are incredibly easy to
handle from React. A framework for declaratively caching relational data with
server side components (like poachdb but for SQL server) would have been
amazing though.

I don't know Turbolinks enough but it doesn't help with the connection
problems I assume?

~~~
d_k_f
No, it does not. Turbolinks keeps a local cache of previously visited pages so
transitions to those seem instantaneous, but this is session-only and can't be
populated in advance.

------
Phillips126
I'm a developer who primarily uses ReactJS for the front-end. I chose the
library years ago because it just made sense to me. I really liked the syntax
(JSX), the lifecycle methods and the quick hot reloads. The only thing at the
time that I really didn't like was the build system (browserify, gulp,
webpack, babel, etc) as I found it overly complicated. Now all of that is
basically invisible with "create-react-app" and I can just get right to
building applications in seconds - life is pretty good.

With each React update however, I worry that ReactJS's scope/concerns is
growing far beyond the view layer that is was initially designed to be. I
worry that it will become just another bloated "framework" with unnecessary
complexity and drive me into the lighter weight and more focused alternatives
such as VueJS or Svelte. Perhaps the React team is getting bored?

IMO I'd like to see a base ReactJS with these advanced features being add-ons
in some fashion. Keep the version I like to use lean and the complexity just
where I like it.

~~~
PKop
> I worry that ReactJS's scope/concerns is growing far beyond the view layer
> that is was initially designed to be.

It is. Because through experience developers realized these concerns need to
be addressed, and handled... by something. It is unavoidable to have a useful
application. Having the framework integrated to help you do so is much less
painful than piecing together separate tools, or having 20 different libraries
construct their own way to do so ( _if_ it is solveable in a uniform way that
simply needs to be advocated and agreed upon).

But in any case, why can't you just not use them?

What is the pain point caused by ignoring the changes... and choosing separate
tools to solve these problems if that's what you prefer?

~~~
runawaybottle
If the Jquery authors said ‘if u don’t like sizzle selector, feel free to use
standard dom functions to grab your elements’

We’d all be pissed if the sizzle selector wasn’t awesome and well thought out
api.

What I keep seeing with React is really bad api design with things like hooks
(because classes are so complicated, someone link that documentation post) and
redux is horrific boilerplate to manage global state.

Ok no problem, don’t use it. Discourse ends there right?

No I’m sorry, reducers, hooks, ‘suspense’ stuff is not intuitive. This needs
to be properly discussed.

Can I possibly even start the discussion at why the hell these things are
being named in this way? Is that not a start? Functions and Classes are
stupid? A debounce function that’s possibly a promise, stuff we know about, is
suddenly like the ‘suspense’ api? Does any thought go into this anymore for
how average developers have to approach this horseshit?

~~~
marcoseliziario
Those are advanced resources. For what they do, they are pretty
straightforward, but if you are just starting, you don't need to care about
reducers, hooks, suspense. You don't even need to do a SPA to take advantage
of react, thus, you don't even need a router to start.

~~~
runawaybottle
You sound like such a shill. You don’t need anything in this life dude. But
let’s say you do, or let’s say a subset of people do, and the feedback they
comeback with is ‘this thing could be a lot better’, and shills like you come
back with ‘well you probably didn’t need this’. Give it a rest.

~~~
marcoseliziario
Well. You're free to improve on it them. Maybe doing something useful would
help you to control your anger issues, dude.

------
throwaway_bad
Throwing promises to emulate algebraic effects seems really hacky.

I wonder if React would've needed to go down this path if they were built by a
different company.

For example Google/Apple/Microsoft all have huge influence over browser
implementations (chrome/safari/edge respectively). They might've been able to
push a ECMAScript proposal for proper language support instead.

It's a very clever hack regardless but it only seems necessary because
Facebook doesn't have control over the whole stack.

(it does seems like Facebook trying to fix this by building their own React-
optimized javascript engine but only for react native on android right now:
[https://facebook.github.io/react-
native/blog/2019/07/17/herm...](https://facebook.github.io/react-
native/blog/2019/07/17/hermes))

~~~
davnicwil
> push a ECMAScript proposal for proper language support instead

I don't think this is the way it does (or should) work, though.

No company should be able to just come up with essentially an application
layer pattern and immediately push that pattern down the stack, just because
it's their idea and they think it's good.

A pattern needs to get a lot of practical usage, be iterated on a lot, and
have strong consensus behind it before it's pushed down the stack to become a
more fundamental building block in ECMAScript / browser APIs.

It's a form of make it work -> make it good -> make it fast. The process
should take _years_. It's what happened with jQuery which eventually inspired
the native DOM selector APIs, and I think the same _is_ happening with React.

I honestly wouldn't be surprised at all to see JSX standardised as part of
ECMAscript within the next 5 years. The rest of the stuff they're doing with
the fibre architecture etc may follow too, eventually, if it turns out to be a
really good idea after years of people using it in practice and agreeing it
really ought to be part of the stack.

~~~
erikpukinskis
I agree. JavaScript obviously has problems but it’s also the most used
development platform of all time.

Part of that is because the runtime API really doesn’t change much. And for
many years the only changes allowed were very tightly scoped: a single new
function call, that takes two strings. Stuff like that. The attitude was “what
is the smallest thing we can do to make it technically possible for to get the
job done” and leave developer ergonomics to the web frameworks.

It forces people to build real platform layers on top of the browser. That
causes fragmentation but it is also a hot crucible for competition. It has led
to arguably the most competitive developer tool landscape of all time.

It’s easy to say “browsers should just standardize on X” and be right.

However it’s exactly the very slow acceptance of standards that had led to
such a strong ecosystem of ideas. So in the aggregate, as you indicate, it’s
not good to land on standards too fast.

------
sktrdie
Any framework that allows me to write _simple code_ which then gets
_automatically_ highly optimized to run efficiently and with high/low priority
based on the user-interaction and effectively removes race-conditions and
makes it more intuitive to deal with loading states is a good thing for me.

In fact this feels so advanced stuff (React's runtime I mean) that it will
probably one day land in the browser. So React's team is just one step ahead
of the others, they are thinking: "what's the least amount of code we can let
developers write so that we can optimize away all the rest of the stuff?".

One thing I'm worried is whether with all these amazing optimizations and very
different code-execution model, we have to rethink some of the valuable simple
lessons of software architecture we learned over the years. For instance, we
have to rethink a bit about how to organize code and how to test it. Some
things that before we could confidently say "this piece of code will run at
this time" will now be a bit more like "not sure when this piece of code will
run".

Cool stuff, but some tradeoffs to consider.

------
jonkoops
This is a good development. Honestly one thing I very much think is a downside
about React is the fact that your template is also JavaScript. Don't get me
wrong this is incredibly powerful and can be very expressive, but it comes at
a cost.

That cost has the same cost as other JavaScript - it's blocking, cannot be
paused and has all the possibilities of de-optimizations that might occur in
the JIT. The Ember team faced a similar problem in the past and I find their
solution to this problem quite intriguing, even in it's obscurity. Instead of
compiling their templates to JavaScript they instead compile them to opcodes
in a binary format which is executed by a virtual machine.

This has several advantages. Since the template file is represented as an
optimized binary the size of the file itself is incredibly small, excellent
since templates can be a large part of your eventual code. Not only that but
since the instructions are opcodes, this mean the VM can pause at a moment
when the browser is too busy with other stuff.

Since a large part of your templates is probably static and not prone to any
changes the template file also indicates which parts of the instructions are
dynamic and which are static. This allows the VM to generate a separate set of
instructions just for subsequent updates, only updating those parts which are
dynamic.

Now I am not saying this is a silver bullet, it is however an interesting and
fresh approach. In case you're interested in this check out the Glimmer site
or Tom Dale's excellent talk (can't recommend this enough) on the subject:

\- Tom Dale's talk: [https://www.youtube.com/watch?v=nXCSloXZ-
wc](https://www.youtube.com/watch?v=nXCSloXZ-wc) \- The Glimmer JS site:
[https://glimmerjs.com/](https://glimmerjs.com/)

~~~
nightnight
> a downside about React is the fact that your template is also JavaScript

Everytime I read this (and it still seems to happens in 2019) I just don't get
it--I don't get why people want to stick to the past. It's the best thing
which could happen, everything is JS, FE development finally got bearable, no,
enjoyable! It freed us from all the subpar patterns before.

~~~
erokar
What is it you don't get? The parent post clearly states why this can have
performance costs. Other modern frameworks like e.g. Svelte solves rendering
without making templates JS.

~~~
nightnight
> performance costs

They are overstated. You are not building Photoshop in the browser 99% of the
time. Dev productivity should have a higher prio => everything in JS and
nobody needs some FE VM with bytecode (wtf, I mean when we already talk about
Ember, Ember interfaces are not really the fastest one despite having their
own small VM).

This is what I don't get, sticking to the past and requiring stuff which
doesn't make sense.

~~~
erokar
Sticking to the past? You talk as if JSX is the final solution in dev
productivity, after which nothing else is even worthy of consideration. JSX
has pros and cons, as does e.g. Vue's and Svelte's templating approaches.
Something even better will surely appear, or already has.

------
couchand
This is a wonderful example of a well engineered solution to the wrong
problem. React is a wonderful view library, and if limited to that use it is
remarkably fast and easy to use.

But the usual way of building things is to treat React as a total web app
framework. The terminology is very confused: they still call it "rendering",
even though it now usually includes data fetching, complex manipulations,
event processing, etc. You just `React.render` once when your page first loads
and then child components take care of the rest. It should really be called
`React.start`.

> The reason for the stutter is simple: once rendering begins, it can’t be
> interrupted.

Rendering should never _need_ to be interrupted. If your app is architected to
have any rendering operation take long enough that it's perceptible to the
user, STOP DOING THAT THING DURING RENDERING.

Want a performant web app? Apply separation of concerns properly, and limit
your use of React to the view layer.

~~~
_bxg1
> If your app is architected to have any rendering operation take long enough
> that it's perceptible to the user, STOP DOING THAT THING DURING RENDERING.

At my workplace we frequently encounter cases where the rendering itself -
just the evaluation of the pure React functions - takes hundreds of
milliseconds, if not several seconds. This is after memoizing every part of it
that can be memoized, after profiling it for places where work can be shaved
off, etc. Sometimes there really is just that much rendering, and unlike other
types of computation, today's React gives you _no_ options for putting that in
a worker or breaking it up. Tabs' single threads mean you can't even _scroll_
in the interim. Concurrent Mode is the only hope we have of solving that case,
other than avoiding it with paging, which is what we currently do.

~~~
paulddraper
> React gives you no options for putting that in a worker or breaking it up.

Isn't that React Fiber? [1]

"Fiber breaks down animation into segments that can be spread out over
multiple frames."

How does that differ from React Concurrent? Are they compatible?

[1]
[https://en.wikipedia.org/wiki/React_Fiber](https://en.wikipedia.org/wiki/React_Fiber)

~~~
_bxg1
So, I'm not sure exactly how Fiber works, but given the context and what I've
read/watched, here's my guess:

Confusingly, there are multiple tiers of "updates" happening in a React app.
One is when your render functions are called to recompute their _React_
element trees. Work can be avoided here via shouldComponentUpdate(), etc.

Once React has this internal data structure, it uses it to do _another_ level
of updates to the actual DOM. This part is totally black-boxed from the
application code, because React has all the information it needs internally to
avoid unnecessary updates at this level.

I think, maybe, that Fiber is specifically focused on this latter stage.
Concurrent Mode would then be the stage 1 equivalent of what Fiber does in
stage 2. This would be why it has an effect on how application code can
actually be written, where Fiber didn't really.

~~~
acemarke
"Fiber" was the rewrite of React's internal render logic (primarily how it
processes the component tree), and was released in 16.0. It's named after the
data structure that is used to track individual pieces of work (roughly on a
per-component basis).

Fiber does specifically divide the overall update process into two general
phases. "Render phase" involves walking the component tree, asking components
what the desired UI should look like, and calculating the diff and necessary
changes based on the previous requested output. Once that's been calculated,
it is applied all at once in the "commit phase".

Concurrent Mode is, loosely, additional modifications to that rendering logic
to enable pausing partway through the "render phase" process, tracking one or
more in-progress versions of render passes, prioritizing them based on the
source of the requested update (user input vs network request, etc), and
recalculating in-progress renders if another higher-priority render was pushed
to the front and committed to the DOM first.

------
nojvek
This seems quite complicated. Rarely the big perf hit is in js. The big perf
hit is usually layout, composite and paint cycles. They are eons slower than
manipulating a virtual dom tree in js.

So I don’t get it. You can’t interrupt the browsers native paint cycle. Once
you say node.appendChild or change some attr/style. The browsers gonna do what
the browsers gonna do.

React was simple. With hooks , concurrent mode, virtual events and mumbo
jumbo. I don’t get it anymore. It’s not a lean mean library that takes minutes
to run and one can’t read the source in a couple of hours

~~~
james_s_tayler
>React was simple. With hooks , concurrent mode, virtual events and mumbo
jumbo. I don’t get it anymore. It’s not a lean mean library that takes minutes
to run and one can’t read the source in a couple of hours

I feel that.

One of the top voted questions was "how do I do a simple form submission?" and
the response was "it all depends on your state management caching behavior". I
think that highlights just how beginner unfriendly some of this stuff has
become.

~~~
JMTQp8lwXL
> the response was "it all depends on your state management caching behavior".
> I think that highlights just how beginner unfriendly some of this stuff has
> become.

What's the alternative? In Angular, the whole problem would've been solved
with their template engine + built-in forms module. But Angular has a huge API
surface.

With React, you have your template engine. Form state can be managed with a
third-party library, like final form. It's no broader of an API Surface than
Angular would be.

So the question is, when were these things ever "beginner friendly"? Were
forms easier 5, 10 years ago than they are to implement today?

~~~
james_s_tayler
>Were forms easier 5, 10 years ago than they are to implement today?

Yes. Less was expected of us. Things have grown and evolved in such a way that
user interfaces can provide much better experiences than they use to be able
to and as the capabilities have grown, so have the expectations. Along with it
the barrier to entry has gone up.

------
burgerzzz
React.js is literally the only reason I'm still in software engineering. I
know I should learn Scala and be a full stack developer again, but at almost
34, I really feel like I've found my niche in frontend React development. I
trusted the React team when they released hooks, and I've never loved coding
more than now. Everything just makes sense, and it seems to always work when
you follow the best practices.

I'm excited to start learning more about Concurrent Mode and Suspense.

------
jbaudanza
As I understand it, the principal behind the VDOM is that renders are cheap
and the cost is is negligible compared to real DOM updates. If this is the
case, why do you need to keep concurrent VDOMs in memory at once? Why can't
you just render the VDOM you need when you need it? I think this is where I'm
getting lost on this new feature.

~~~
danabramov
The thing that’s slow is _arbitrary JS code people write in components_. VDOM
is not the point there. We want to make arbitrary JS code people write non-
blocking, by using components as the “units of work” where we can yield.

Really though, you’re over focusing on the CPU part. The IO part is much more
interesting.

~~~
jbaudanza
When you say "yield", you're talking about render functions throwing a
Promise, right? Is there another kind of yield that _arbitrary JS code people
write in components_ can do that I'm missing?

~~~
erikpukinskis
Render functions, to my knowledge, can’t return a promise.

(And you don’t throw a promise, you return and reject it)

The issue at hand is fully synchronous render functions that, e.g., go through
a giant list of objects and call a bunch of other render functions on each one
synchronously.

This change allows that one function to finish, and interaction to continue
before all the children render.

~~~
jbaudanza
The new suspense API works by throwing Promises when the data isn't ready yet.

~~~
erikpukinskis
I’m not sure what you mean by “throwing promises”...

You mean returning unresolved promises? Or returning rejected promises? Or
just throwing an error?

~~~
acemarke
Literally, _throwing_ a Promise.

React will catch promises thrown during rendering, and treat that as a request
to "suspend" the component and come back to it later once the promise has
resolved.

------
EastSmith
The version control analogy in the description was spot on, but a good demo is
worth a thousand words, so I will be waiting for a good demo to make
conclusions.

~~~
danabramov
It might be asking a lot but to form the right impression, I would really
suggest that you get through these docs:

1\. [https://reactjs.org/docs/concurrent-mode-
suspense.html](https://reactjs.org/docs/concurrent-mode-suspense.html)

2\. [https://reactjs.org/docs/concurrent-mode-
patterns.html](https://reactjs.org/docs/concurrent-mode-patterns.html)

I spent the last 48 hours writing them, and I think they answer your questions
and contain many, many demos.

~~~
koolba
I'm still working my way through the suspense doc (very nice so far...) so
please bear with this "in flight" thought.

Does having an external state tracking system like Redux combined with a
tracking a "loading state" solve the in-flight rendering item? My initial take
is that this allows for a simplified model where data is loaded directly in
components without the wrapping dance for tracking client load status.

~~~
danabramov
The meat of this thing is in the 'Patterns' doc. That's the kind of stuff
Redux isn't equipped to do.

------
zyang
"For IO-bound updates (such as fetching code or data from the network),
concurrency means that React can start rendering in memory even before all the
data arrives, and skip showing jarring empty loading states."

What is there to render but loading states when there's no data?

~~~
jacobr
Buttons, headings, labels... Will all be ready when your data arrives.

~~~
JMTQp8lwXL
You can already do that without concurrent mode, though. Let's say you have a
navbar (your website's header), a list of things asynchronously retrieved from
an API, and a footer.

const myApp = () => (

    
    
      <Header />
    
      <Body />
    
      <Footer />
    

);

Body can make the network request, and store the result in state. Since the
network request took 200ms, Header and Footer have already rendered.

------
anderspitman
On a purely technical level, this is really cool. But I can't help but wonder:
if this level of complexity is the answer, maybe we're asking the wrong
question.

~~~
Grzegrzolka
I am huge React fan, but when I see how complicated are some of the modern
React codebases in some "leading" companies I have a strong feeling that we
will soon need to go back to drawing board and hit some kind of reset button.
As I said, I love React ecosystem, but there is something fundamentally wrong
with most front-end developers today. They build bigger and bigger SPAs
because they are confident that React ecosystem makes it maintainable, well
good luck maintaing React/Redux/Graphql/hooks/bazillion-libs after 5 years.
Abstraction is good, but it has its limits.

~~~
nickdandakis
Sometimes frontend developers overengineer their solutions, yes.

Sometimes you need a more complicated solution for a complicated set of
requirements.

Do you need GraphQL? Nope!

Do you need GraphQL for an application that needs to fetch a lot of highly
relational data with nested objects? No, but it sure would be more optimal to
just ask for what you need in one request in the shape you expect, instead of
either:

a) Multiple REST API calls that you need to combine and coordinate in the
frontend

b) A specialized REST API call that gives you all the data you need in the
shape you want, but it isn't very RESTful

c) A REST API call with a bunch of `with[]` params (a la Laravel) that
indicate what nested objects you'd like, but not their exact shape

So, which is more maintainable then?

—

The other wild misconception I see time and time again is this:

Of the five things you mentioned "React/Redux/Graphql/hooks/bazillion-libs",
only the first one is React, and the second-to-last (Hooks) of which it is
optional.

The rest are dependencies you opt for, hopefully after weighing pros and cons.
You don't need to use Redux, GraphQL, react-table, whatever other dependency
in your React web application.

Please separate out React from React-based codebases from code architecture.
They're not one in the same.

~~~
Grzegrzolka
I just don't buy this idea that there is some kind of separation between React
library and React as a platform. I'm building SPAs since 2008, been to too
many front-end meetups, have friends in so many different companies its hard
to count. NOBODY is using React as a library. Banks, shops, news sites, you
name it, everyone is using React+Redux+Typescript+bazilion-libs. Graphql is
not a standard yet but it is already very popular, basically every new hired
Dev adds new libs or switches to something else. It's a mess.

~~~
nickdandakis
The thing is, I don't disagree that a large (if not majority) number of
developers reach for dependencies by default, instead of carefully considering
patterns first.

I don't think bundling React the view library, Redux the state management
library, Typescript the Javascript superset, GraphQL the API query language,
Webpack the bundler as one "React the platform" is helpful.

I'd like to see the developers that automatically merge all of these
technologies together by default because everyone else does it (or worse,
because X Big Tech Co does it) to start questioning and exploring other
options. I'm not sure how to get there, and maybe my comment above is my
contribution towards convincing readers to reconsider their understanding of
the React ecosystem.

You're right though, it is a mess. I think the mess comes from people and how
they code, not so much this specific library nor the language.

~~~
mattacular
These new frameworks and things like "create-react-app" have made it easier
and easier for junior developers to make immensely complicated apps with
immensely complicated tool chains. I think that has a lot to do with how
things have gotten to the point described in your comment and many of the
others. As you start reading tutorials about Vue or React they tend to quickly
stray into other dependencies, and webpack or whatever. The web has gotten
more complex. The only way to navigate it wisely is to become wise through
experience. There are no shortcuts but we've definitely made it easier for new
developers to stumble into a mess.

------
boucher
Pretty interesting. Hope someone also writes a summary of how it works. Are
they computing the tree in a worker, or have they just modified the rendering
api itself to somehow be interrupt-able?

~~~
boucher
Seems someone has written some of it up here:
[https://github.com/acdlite/react-fiber-
architecture](https://github.com/acdlite/react-fiber-architecture)

~~~
petetnt
acdlite has written most of the implementation work that lead to this feature

------
adriancooney
Huh. Throwing promises to manage concurrency is kind of neat and scary
(because it's new and different). I remember there was huge performance hit
from functions containing `throw` statements in V8, has that been addressed
(in V8 or in this project)?

~~~
danabramov
If you’re blocked on network, throw is not gonna put a dent in that. We only
use throwing when work is blocked on IO.

------
anderspitman
Rich Harris' excellent talk Rethinking Reactivity has an interesting section
where he compares a React Concurrent Mode demo to Svelte:
[https://youtu.be/AdNJ3fydeao?t=1128](https://youtu.be/AdNJ3fydeao?t=1128)

~~~
danabramov
This comparison focuses on just one aspect of Concurrent Mode and misses the
big picture. I'll believe it when I see these demos ported to Svelte:

[https://reactjs.org/docs/concurrent-mode-
patterns.html](https://reactjs.org/docs/concurrent-mode-patterns.html)

~~~
anderspitman
So you're saying Svelte might have the best performance, but Concurrent Mode
makes it much easier to achieve medium performance (there certainly would be
value in that)? Sorry, haven't had time to read all the material yet.

~~~
danabramov
I'm saying that I don't see how you're going to implement these "pending
loading state" patterns in Svelte but I'd sure like to be proven wrong.

It doesn't make sense to try to summarize that page. I've been writing it for
two days and it's the shortest that I could compress the essence. I'd be happy
to respond to questions you'll have after reading :-)

~~~
thebosz
You deserve a vacation!

------
goliathDown
I'm relatively new to ReactJS and professional web development, and I've been
using (and learning) react-redux. The layer schema makes sense to me; React
handles user input, redux manages state, and react-redux ties them together.

If react does a better job at speedily handling user input to the point of
seamless interaction, then I suppose that would be good. What are we losing
from choosing to make a layer itself responsible for the speed of returning
output (rendering) from input (user interactions)?

------
holler
As someone who mostly uses ember.js in the day-to-day, I'm wondering how this
compares to the amazingly great ember-concurrency library that uses
generators?

~~~
bnjmn
Here's their official position on generators:
[https://github.com/facebook/react/issues/7942#issuecomment-2...](https://github.com/facebook/react/issues/7942#issuecomment-254987818)

~~~
holler
very insightful, thank you

------
duxup
It's certainly a problem I sort of dance around in React planning how and when
something might render based on what is going on, the amount of rendering and
such, and the dance is somewhat never ending.

~~~
mosdl
One of the main weaknesses of vdom is that React now has to solve these issues
that browsers already do natively.

~~~
ng12
Can you elaborate? At a minimum vdom is just doing work you would have had to
do manually with DOM apis.

~~~
mosdl
With regular dom/javscript, you can be typing into an input field and updating
unrelated DOM and the typing should not be impacted much (unless you are
changing a lot of DOM and spiking the cpu).

But with React it has to reconciliate the input field.

~~~
acemarke
"controlled inputs" are certainly the recommended React idiomatic pattern, but
you can use standard uncontrolled inputs if you want.

------
foota
This was the biggest pain point I had when developing a vanilla react app
circa two years ago. It's great to see that they've come up with a neat
solution that works out of the box!

------
XCSme
As an experienced front-end developer I must say that I don't really
understand why the complexity of building websites is growing instead of going
down. We have build thousands of front-end frameworks and all of them try to
solve the same issues that should have been solved by the browsers themselves
a long time ago. We implement complex "routers" and "server-side-rendering" to
show specific content when the URL in the address matches a specific value,
while the entire web architecture was made exactly for this purpose, to show
some content when you go to an URL. Tens of years of "evolution" and we just
keep making everything slower and more complex for no reason, apart from being
bored or wanting to be trendy.

I know all those frameworks exist to solve a specific problem, but while doing
so we are creating hundreds of problems that never existed before.

~~~
kylemh
You likely don't have the problems that Facebook is trying to resolve with
React.

Namely, developing something once and having it work ideally everywhere on the
planet (slow network vs. fast network).

They're worried about shaving kilobytes here and there - concurrent mode helps
to dynamically render/load items in an order that makes sense for people on
slow networks where it wouldn't even matter for people on fast networks.

~~~
democracy
And this is fine but why the facebook-scale problems solver becomes a
mainstream library then? How many companies have these problems?

~~~
bcrosby95
This is how things have worked in tech for at least the last 10 years (which
is when I first noticed it). People that don't have the same problems as
FAANGs cargo culting FAANG tech because it works for FAANG.

------
shadowgovt
I like what I see from Suspense. I've had to implement that pattern myself a
couple of times before in Angular; it's common enough to justify a standard
approach.

EDIT: This is better than what I've implemented. My solutions have involved
data-load waterfalls. I'll have to crack the code open and see how Suspense is
pulling this approach off; it's pretty cool!

------
aocenas
Anybody knows whether generator functions were considered and if they were,
reasons why they were not used for this?

~~~
bnjmn
Yes! I was also curious about this, because I'm sure you could make
generators/yield work for asynchronous interruptible rendering, but here's
what the React team has to say:
[https://github.com/facebook/react/issues/7942#issuecomment-2...](https://github.com/facebook/react/issues/7942#issuecomment-254987818)

------
orangepanda
> It would be nice if we could “skip” it and wait for some content to load
> before transitioning to the new screen.

Yes please! I do hope this pattern catches on. Not only are full page loading
screens on every interaction obnoxious, I’m sure they also require an epilepsy
warning.

------
iamleppert
This isn't new. You've always been able to build up a DOM element in memory
before adding it to the tree. You can even use something like
requestAnimationFrame to incrementally build and not block (useful for things
like long lists etc).

~~~
danabramov
For sure. But I’d love to see a demo of features described here that’s as
expressive.

The challenge isn’t the low level mechanism. It’s how to make it composable so
people can build their own abstractions.

[https://reactjs.org/docs/concurrent-mode-
patterns.html](https://reactjs.org/docs/concurrent-mode-patterns.html)

------
c-smile
Or just implement React natively so speed will not be an issue:
[https://sciter.com/sciter-4-4-0-0-with-reactor-on-
board/](https://sciter.com/sciter-4-4-0-0-with-reactor-on-board/)

------
rubyn00bie
Is this just using generators to allow things to be interrupted and scheduled?
Or is it more fancy than that?

~~~
aocenas
Last time I seen an explanation for this, they were talking about throwing and
catching promises. So you could probably implement suspense with an error
boundary just checking if the error you got is actually promise and if so wait
for it to resolve until rerendering.

But reading this I think there is a bit more to it and I would assume for some
things to work you have to actually try rerendering on some scheduler not just
wait for promises to resolve (like they mention in how multiple Suspense
components are aligned and rendered together if they resolve in close
succession)

~~~
bnjmn
Here's a comment from Sebastian M (React core team member) about why they
chose not to use generator functions:
[https://github.com/facebook/react/issues/7942#issuecomment-2...](https://github.com/facebook/react/issues/7942#issuecomment-254987818)

------
kansface
I'm left scratching my head a bit from this blog post. In
[https://reactjs.org/docs/concurrent-mode-
suspense.html](https://reactjs.org/docs/concurrent-mode-suspense.html),
current pitfalls of fetching data are explored including waterfalls
(sequential loading spinners for nested components) and data races.

The way we currently solve these problems, which for some reason didn't make
it into the examples, is with Redux:

    
    
      fetchProfileData()
      const ProfilePage = connect((state) => ({ user: state.user, posts: state.posts})(ProfilePage)
    

In truth, we'd also track a loading and error state as well. This solution is
not subject to data races or waterfalls.

One could argue that their new implementation provides a better interface...
but I'm not so sure. The final ProfileDetails won't work outside a Suspend
because the Suspense API is Throwing Promises [1]. In fact, it crashes the app
:-/

    
    
      Note how we eliminated the if (...) “is loading” checks from our components. This doesn’t only remove boilerplate code, but it also simplifies making quick design changes.
    

Yeah, I did note that, but is it a good thing?! Rendering in React is
currently localized to the render function of the Component itself! Its rather
easy to miss the function call that is throwing a promise during rendering to
cause itself to not be rendered! Suspense is a hidden interface to delegate
rendering to a parent - perhaps an even more error prone Context API.

All in all, this feels like Hooks to me - the trivial examples in the Docs
seem perfectly cromulent, but in practice, the ergonomics are so bad that any
time I try to use them, I am forced to spend several hours debugging stuff
because they lose predictability when composed. Perhaps this won't be so bad
in practice, but I'm having a hard time imagining how to compose components
that interact with Suspense. Of course, I'd love to be wrong (about the API)
or proven wrong and everything turns out to be magical. Maybe TS makes it
perfectly obvious in practice, but maybe it generates a ream of gibberish
instead.

The true sleight of hand in most of the examples is to kick off `fetch`ing
before a component gets mounted that needs the data:

    
    
      // Kick off fetching as early as possible
      const promise = fetchProfileData();
      
      function ProfilePage() {}...
    

As far as I can reason, there is no good way to do this. The data dependency
graph is naturally defined by the component graph: after all, components know
what data they need to render, but that graph can't be resolved until after
they are actually rendered. So, you end up defining it in two places with an
implicit coupling or via HOC or get a waterfall. I'd be open to some magic
here.

1\. [https://codesandbox.io/s/frosty-hermann-
bztrp](https://codesandbox.io/s/frosty-hermann-bztrp) \- see fakeAPI.js
(couldn't figure out how to link to it.

~~~
danabramov
>The way we currently solve these problems, which for some reason didn't make
it into the examples, is with Redux:

As the _author_ of Redux I can assure that it’s not designed for — or capable
of — providing the features described on this page:

[https://reactjs.org/docs/concurrent-mode-
patterns.html](https://reactjs.org/docs/concurrent-mode-patterns.html)

Hope that makes sense.

Regarding fetching, as the page says, in practice we use Relay for that. If
you want to look at how it works in production, the page does link to Relay
docs.

~~~
kansface
> As the author of Redux I can assure that it’s not designed for — or capable
> of — the providing thee features described on this page... Hope that makes
> sense.

Sure! Seems like we are talking past each other (these problems being
waterfalls and data races and the examples coming from
[https://reactjs.org/docs/concurrent-mode-
suspense.html](https://reactjs.org/docs/concurrent-mode-suspense.html)).

~~~
acemarke
Right, and as a _current_ Redux maintainer, I can also assure you that Redux
does nothing to solve those problems :)

Redux is simply a synchronous external data store. It does nothing in regards
to how you fetch your data. While React-Redux does trigger UI re-renders when
the store is updated, we rely on React's own scheduling capabilities to handle
actually updating the UI. So, no, Redux definitely does not solve the patterns
described in those docs.

I'm hopeful that we may be able to eventually build some integrations between
Redux and Suspense at some point in the future, but frankly we've been waiting
for actual docs and examples of how all this stuff is _meant_ to work.
Conveniently, we now actually have some (thanks Dan!), but it's still going to
take a long time to absorb what the APIs are and what techniques may be
possible.

------
manigandham
These frameworks should be architected to support async/await scenarios
natively instead of all these convoluted workarounds. Promises/async have ben
around long enough.

EDIT: JS is already dynamic. If a function returns a promise then it should be
awaited and render blank or nothing in the vdom. This is obvious, except in JS
where architecture prefers synchronous-only design with async being an
afterthought.

~~~
arcticfox
React's prioritization of features has led to it being one of the most
successful frameworks of all time, I'm not sure how useful it is to suggest
they should have started with this from the beginning. It's been
overwhelmingly successful without this feature.

~~~
dosy
The illogical adoption of React must not be questioned, even in the face of
its poor performance and ugly syntax. One must never note that perhaps it is
simply a cultish adoration, or faddish adherence to popular mass opinions,
that leads to "popularity" mattering more than practicality.

So what if React is massively bloated, stupid syntax, can't use regular HTML,
can't use regular CSS, can't use async/await, have to do everything a special
way...literally, SO WHAT. It IS REACT! OMG behold it's glory. It came from FB,
maybe if we use it we can scale like FB!

Omg the idiocy. But keep on slavishly following the next front-end dev trend.
I can't tell whether front-end dev culture is a massive circle-jerk or cargo
cult. And don't mention the irrational hate attempted to be heaped onto anyone
who _dares_ question the programmatic thinking of the official line of the
React Appreciation Society.

~~~
hombre_fatal
Is there anything more in-bad-faith than assuming everyone who uses X is just
an idiot, trend-follower, or beginner? Unlike you, the Enlightened One?

Why not just ask people why they use X? Plenty of veteran developers on HN
could tell you why they like React despite a sea of alternatives, but it's
easier to just cast aspersions instead of understanding.

It's a shame to see this on HN which is supposedly a community of craftspeople
who build things. If you can only come up with insults for why another group
of people do something, it's time for you to get up off your ass and ask
someone in that group. And this extends beyond just engineering, it's how you
understand other people in general.

------
runawaybottle
I just want to take a moment and say , while Dan is smart and has probably the
right patterns we all need to implement, he is a horrific API writer.

So none of this could be abstracted right? Like, jesus, not functions but
reducers, not straight for ‘cancelRender’ but ‘Suspense’ Api.

There was a guy once upon a time that said ‘$(‘.comments’)’, that makes sense
, it’s intuitive. These APIs are just getting dumb from a common sense
perspective.

~~~
leerob
Dan didn't write the entire API himself. I'm sure the whole React core team
contributed in some fashion and it went through various code reviews. No need
to bash.

~~~
runawaybottle
Well you know not to be too snarky, but some of these framework writers now
days would argue ‘bashing has its place, not everyone needs to be bashing’

I’m just showing you that a shitty version of discourse is available if you
need it for your use case.

