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

New Reconciler Infra #6690

Merged
merged 1 commit into from
May 11, 2016
Merged

Conversation

sebmarkbage
Copy link
Collaborator

This is an outline for the new reconciler infrastructure.

I created a noop renderer to have something to get started from.

I split the reconciler folder into old and new, as well as shared. I put shouldUpdateReactComponent in shared as an example of a utility that can easily be shared between both. I plan on breaking out more utilities like these.

Builds on top of #6682

@ghost
Copy link

ghost commented May 5, 2016

@sebmarkbage updated the pull request.

@gaearon gaearon mentioned this pull request May 5, 2016
@jayphelps
Copy link
Contributor

jayphelps commented May 5, 2016

#6170 doesn't really explain these architecture changes. e.g. high vs. low priority renders, incremental and the how and why. Anywhere I can see the discussions on this or have they thus far been informal and undecided and this PR is just to flesh them out? 👯

@gaearon
Copy link
Collaborator

gaearon commented May 5, 2016

have they thus far been informal and undecided and this PR is just to flesh them out?

Yes, I think this is just @sebmarkbage trying to create a useful proof of concept in a way that makes sense to him. The goals are simple: change React from deep recursive rendering on every change to some kind of scheduling.

The way I understand this PR is the following. For scheduling to work, we need some kind of priority system, or otherwise there is no way for React to know which updates should be processed first. “Low” and “high” is the simplest possible way to describe priorities. We don’t know if more kinds of priorities would be helpful, so starting with two makes sense to me. How they are used is an open question, but it’s easy to imagine some options. For example, we might want to schedule high priority updates for something is interacting with (e.g. pressing a Like button) because UI should be responsive to feedback. On the other hand, rendering loading data might be a lower priority (i.e. it’s better to render a new story in the feed with a small delay than cause an animation happening at the same time to drop frames).

If there is any specific algorithm in mind, it’s in @sebmarkbage’s head, but I think he’s just fleshing out a system capable of rendering existing React components with priorities. There’s really not much to it aside from what I wrote above. The existing reconciler code is deeply OO and relies on recursive dynamic dispatches (e.g. mountComponent() of any composite component causes mountComponent() of whatever it renders to) so it’s hard to shove priorities into the existing system. This is why @sebmarkbage is starting the reconciler from scratch in this PR. It’s not clear how long it will take to get to the feature parity, but we’ll see.

@gaearon
Copy link
Collaborator

gaearon commented May 5, 2016

Also, for the record, I don’t understand what Fibers are either yet 😄 . The EffectHandler and EffectTag reminds me of this post by @sebmarkbage about algebraic effects. The gist of “effects” in Eff is that functions can throw “effects” and not just errors, and their callers can “catch” these effects, do something, and then yield back to the child function.

This sounds a lot like what React components want to do. Today, we can say setState() is like an effect because it schedules an update to the system. But we want React components to be able to do more and to provide more ways for children and parent to communicate. This is crucial for supporting layout in React: you want a child to “yield” its size to the parent while rendering so that the parent can use this size to set the child’s position. Some notes on a system like this have been posted in react-future two years ago but this wasn’t being worked on. However, two months ago @sebmarkbage, inspired by effects in Eff, made another prototype of a system that would support layout, also in react-future.

Another example is context: we want context updates to be fast, as it is useful for layout and animations, but the current system involves walking the whole tree to update the context which causes issues like #2517. If context was also an effect, and we built support for effects handled by parent components (or React itself) in React, this would probably get solved as well.

Since we don’t actually have algebraic effects in JavaScript, my guess would be that Fibers are some sort of internal abstraction for connecting functions that “throw” effects directly to the functions that handle them. But this may change any day as @sebmarkbage’s still trying different approaches to see what is minimally needed to implement a scheduling reconciler while ensuring future use cases like layout in React are supported better than in the current model.

I might be totally wrong though!

You might also find this helpful: https://github.com/reactjs/react-basic. Especially https://github.com/reactjs/react-basic#algebraic-effects. This is pretty much a braindump of what @sebmarkbage has been thinking about for the past few months. I think the new reconciler will move closer to this conceptual model of React than the existing one, although of course implementation details will still differ from the conceptual model because we live in a real world. 😄

@sebmarkbage
Copy link
Collaborator Author

Fibers as a concept is essentially https://en.m.wikipedia.org/wiki/Fiber_(computer_science) reimplemented in user space.

But yea, I don't really know what I'm doing yet. I have a rough idea.

On May 5, 2016, at 4:47 AM, Dan Abramov [email protected] wrote:

Also, for the record, I don’t understand what Fibers are either yet 😄 . The EffectHandler and EffectTag reminds me of this post by @sebmarkbage about algebraic effects. The gist of “effects” in Eff is that functions can throw “effects” and not just errors, and their callers can “catch” these effects, do something, and then yield back to the child function.

This sounds a lot like what React components want to do. Today, we can say setState() is like an effect because it schedules an update to the system. But we want React components to be able to do more and to provide more ways for children and parent to communicate. This is crucial for supporting layout in React: you want a child to “yield” its size to the parent while rendering so that the parent can use this size to set the child’s position. Some notes on a system like this have been posted in react-future two years ago but this wasn’t being worked on. However, two months ago @sebmarkbage, inspired by effects in Eff, made another prototype of a system that would support layout, also in react-future.

Since we don’t actually have algebraic effects in JavaScript, my guess would be that Fibers are some sort of internal abstraction for this pattern of “throwing” effects and having callers handle them. But this may change any day as @sebmarkbage’s still trying different approaches to see what is minimally needed to implement a scheduling reconciler while ensuring future use cases like layout in React are supported better than in the current model.


You are receiving this because you were mentioned.
Reply to this email directly or view it on GitHub

@ghost
Copy link

ghost commented May 7, 2016

@sebmarkbage updated the pull request.

@ghost
Copy link

ghost commented May 10, 2016

@sebmarkbage updated the pull request.

}

ReactNoop.render(<Foo />);
console.log('Nothing done');
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no (unmocked) logs in tests please

@sophiebits
Copy link
Collaborator

Meh, okay.

This is an outline for the new reconciler infrastructure.

I created a noop renderer to have something to get started from.

I split the reconciler folder into old and new, as well as shared.
I put shouldUpdateReactComponent in shared as an example of a
utility that can easily be shared between both. I plan on breaking
out more utilities like these.
@sebmarkbage sebmarkbage changed the title RFC: New Reconciler Infra New Reconciler Infra May 11, 2016
@ghost
Copy link

ghost commented May 11, 2016

@sebmarkbage updated the pull request.

@sebmarkbage sebmarkbage merged commit cf15788 into facebook:master May 11, 2016
@zpao zpao added this to the 16.0 milestone Jun 1, 2016
@zpao
Copy link
Member

zpao commented Jun 3, 2016

This (and to a lesser extent the followups) are going to make it tricky to continue cherry-picking into the 15 release due to file moves. Is there any risk in cherry-picking this (and the other fiber changes) as well? It doesn't look like anything in current code has really changed. They aren't part of public modules so seems like it should be pretty safe. We could even exclude the whole fiber/ dir from the package if we want.

@zpao zpao modified the milestones: 15-next, 16.0 Jun 6, 2016
@zpao zpao removed the semver-major label Jun 6, 2016
@zpao
Copy link
Member

zpao commented Jun 6, 2016

After discussing offline - going to take this and some other PRs in 15. While they are currently built in the same pipeline, they aren't part of our exposed API and thus are exempt from semver rules.

zpao pushed a commit to zpao/react that referenced this pull request Jun 8, 2016
This is an outline for the new reconciler infrastructure.

I created a noop renderer to have something to get started from.

I split the reconciler folder into old and new, as well as shared.
I put shouldUpdateReactComponent in shared as an example of a
utility that can easily be shared between both. I plan on breaking
out more utilities like these.
(cherry picked from commit cf15788)
zpao pushed a commit that referenced this pull request Jun 14, 2016
This is an outline for the new reconciler infrastructure.

I created a noop renderer to have something to get started from.

I split the reconciler folder into old and new, as well as shared.
I put shouldUpdateReactComponent in shared as an example of a
utility that can easily be shared between both. I plan on breaking
out more utilities like these.
(cherry picked from commit cf15788)
@zpao zpao modified the milestones: 15-next, 15.2.0 Jun 14, 2016
@gaearon
Copy link
Collaborator

gaearon commented Jun 8, 2017

It’s not clear how long it will take to get to the feature parity, but we’ll see.

I guess we know that now. 😄

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

Successfully merging this pull request may close these issues.

5 participants