-
Notifications
You must be signed in to change notification settings - Fork 48.8k
ReactDOMComponentTree #5190
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
ReactDOMComponentTree #5190
Conversation
it('should be able to switch between rendering null and a normal tag', () => { | ||
spyOn(console, 'log'); | ||
|
||
it.only('should be able to switch between rendering null and a normal tag', () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it.only
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, fixed.
@spicyj updated the pull request. |
569414c
to
2188cf8
Compare
@spicyj updated the pull request. |
@spicyj updated the pull request. |
What is the big picture here? Getting rid of |
Getting rid of hierarchical IDs (replacing them with numbers, probably) and the giant hash map we have in ReactMount. We can probably kill data-reactid entirely when not using server-side rendering. |
@spicyj My hope is that we can kill |
@@ -52,7 +52,7 @@ describe('ReactDOMComponent', function() { | |||
var stubStyle = container.firstChild.style; | |||
|
|||
// set initial style | |||
var setup = {display: 'block', left: '1', top: 2, fontFamily: 'Arial'}; | |||
var setup = {display: 'block', left: '1px', top: 2, fontFamily: 'Arial'}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's this about? Behavior change?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Styles may be unitless if they are integers, but strings must specify units if required (unitless strings may fire a warning). This looks fine to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jimfb recently merged a PR that adds a warning for this case but it only checked the create case, not the update case which we use for createElement. I fixed that so the test for the warning passes with useCreateElement and fixed this test to not warn.
@jimfb I'm operating under the assumption that browser extensions will insert extra nodes into our markup and we need to skip over them. |
Make sure you do your react-native homework |
@jimfb FYI, we can already kill data-reactid for server-rendered markup, it's rather trivial as long as you're ok with doing a fast pass over all the nodes once when starting the client. |
@spicyj updated the pull request. |
We can do that trivially here too by changing precacheChildNodes to not look at IDs and just match up the nodes – but I'm worried about finding extra nodes. |
@spicyj We can always mark the nodes with just |
That's true, but I don't think including a numeric ID ( |
I tend to agree - if we find an unexpected node while restoring a SSR DOM tree, we can just kill it with fire. We don't even need a flag on the nodes to do that. |
@spicyj |
de4a18f
to
7ace2b9
Compare
@spicyj updated the pull request. |
@jimfb @sebmarkbage The last two commits (edit: more by the time you read this, start with the one called "Events:") add events support so we don't rely on hierarchical IDs for events either. (Sorry for piling it all into the same PR – but github sucks at stacking PRs and I didn't want to merge this to master quite yet.) Either of you want to take a look? I'm a little nervous but all the FB test flows worked the first time with this applied. |
@spicyj updated the pull request. |
Did a quick benchmark of rendering a PE-like hierarchy with Electron (Chrome) with a cold and warm JIT using my perf-counters as the timestamp. With a warm JIT (rendering the hierarchy 100 times before measuring anything): This PR is 3.3% faster than master. With a cold JIT, createElement looks a little bit slower (but this PR helps more compared to master!). Our deltas of Not sure if there are things we can do to improve the speed of createElement. |
@spicyj Just for context, I assume those are React rendering times + |
There's probably some painting involved. I intentionally forced layout: I wanted to make sure all the markup was parsed to make sure the HTML mode wasn't doing stuff lazily. Any ideas on how to keep that guarantee while avoiding painting (and layout)? |
@spicyj I'd assume that would just force layouting, realistically rendering/painting should only happen after JS execution ends. I'm pretty sure |
You're probably right. I tried it again without the forced layout and it's about 24ms (on master: 210ms vs 186ms) faster on all five numbers, so the percentages are proportionally the same but go up a little because of a smaller base. Cold JIT, just React.render (no layout): [5.5%, 10.8%, 9.2%, 10.0%]. |
Numerical IDs are in #5205. Also, devtools don't work with this because they currently rely on |
Initial render can still be a markup string.
New module! With this, we have a new module that uses the component tree to store DOM nodes. Most of the logic in this file relates to markup adoption -- if we were to drop that (along with server rendering) this file could just be a `return inst._nativeNode;`. This works with useCreateElement only because we need to reference each node as it's created. Events is now the only thing using ReactMount.getNode -- I'll introduce pointers back from the DOM nodes (and a `ReactDOMComponentTree.getInstanceFromNode`) and make that work.
Next step: take advantage of having the native instances in EventPropagators instead of converting right back to IDs.
This removes SimpleEventPlugin's dependency on ReactMount.getID.
@spicyj updated the pull request. |
Merged in #5205. |
New module! With this, we have a new module that uses the component tree to store DOM nodes. Most of the logic in this file relates to markup adoption -- if we were to drop that (along with server rendering) this file could just be a
return inst._nativeNode;
.This works with useCreateElement only because we need to reference each node as it's created.
Events is now the only thing using hierarchical IDs and
ReactMount.getNode
-- I'll useReactDOMComponentTree.getInstanceFromNode
to make that work.