ReconArt Total Reconciliation Lifecycle - Introduction & Overview
React Lifecycle and Reconciliation
Transcript of React Lifecycle and Reconciliation
Something about Lifecycle
Something about Lifecycle
componentWillMount
Something about Lifecycle
componentWillMount
componentDidMount
Something about Lifecycle
componentWillMount
componentDidMount
Mounting
Something about Lifecycle
componentWillMount
componentDidMount
Mounting
render
…
Something about Lifecycle
Something about Lifecycle
componentWillReceiveProps
Something about Lifecycle
componentWillReceiveProps
shouldComponentUpdate
Something about Lifecycle
componentWillReceiveProps
shouldComponentUpdate
componentWillUpdate
Something about Lifecycle
componentWillReceiveProps
shouldComponentUpdate
Pre-updating
componentWillUpdate
Something about Lifecycle
componentWillReceiveProps
shouldComponentUpdate
Pre-updating
render
…
componentWillUpdate
Something about Lifecycle
Something about Lifecyclerender
Something about Lifecycle
componentDidUpdate
render
…
Something about Lifecycle
componentDidUpdatePost-updating
render
…
Something about Lifecycle
componentDidUpdate
componentWillUnmount
Post-updating
render
…
Something about Lifecycle
componentDidUpdate
componentWillUnmount
Post-updating
render
…
Unmounting
The usage of React is intuitive
The usage of React is intuitiveWe re-render whenever state changes
The usage of React is intuitiveWe re-render whenever state changes
Re-rendering seems expensive…
The usage of React is intuitiveWe re-render whenever state changes
Re-rendering seems expensive…But the truth is
The usage of React is intuitive
React is FAST!!!
We re-render whenever state changesRe-rendering seems expensive…
But the truth is
The usage of React is intuitive
React is FAST!!!
We re-render whenever state changesRe-rendering seems expensive…
But the truth is
WTF???
BatchingSub-tree Rendering
Batching• Whenever you call setState on a component,
React will mark it as dirty. At the end of the event loop, React looks at all the dirty components and re-renders them.
• This batching means that during an event loop, there is exactly one time when the DOM is being updated. This property is key to building a performant app and yet is extremely difficult to obtain using commonly written JavaScript. In a React application, you get it by default.
Batching• Whenever you call setState on a component,
React will mark it as dirty. At the end of the event loop, React looks at all the dirty components and re-renders them.
• This batching means that during an event loop, there is exactly one time when the DOM is being updated. This property is key to building a performant app and yet is extremely difficult to obtain using commonly written JavaScript. In a React application, you get it by default.
Sub-tree Rendering• Whenever you call setState on a component,
React will mark it as dirty. At the end of the event loop, React looks at all the dirty components and re-renders them.
• This batching means that during an event loop, there is exactly one time when the DOM is being updated. This property is key to building a performant app and yet is extremely difficult to obtain using commonly written JavaScript. In a React application, you get it by default.
Sub-tree Rendering• Whenever you call setState on a component,
React will mark it as dirty. At the end of the event loop, React looks at all the dirty components and re-renders them.
• This batching means that during an event loop, there is exactly one time when the DOM is being updated. This property is key to building a performant app and yet is extremely difficult to obtain using commonly written JavaScript. In a React application, you get it by default.
With shouldComponentUpdate, you have control over whether a component should be re-rendered.
Sub-tree Rendering• Whenever you call setState on a component,
React will mark it as dirty. At the end of the event loop, React looks at all the dirty components and re-renders them.
• This batching means that during an event loop, there is exactly one time when the DOM is being updated. This property is key to building a performant app and yet is extremely difficult to obtain using commonly written JavaScript. In a React application, you get it by default.
shouldComponentUpdateThis function is going to be called all the time, so you want to make sure that it takes less time to compute the heuristic than the time it would have taken to render the component, even if re-rendering was not strictly needed.
React Reconciliation
React Reconciliation
a.k.a. Diff Algorithm
Why Another Tree Diff Algorithm?
Why Another Tree Diff Algorithm?
O(n 3)
Why Another Tree Diff Algorithm?
O(n 3)
1000 nodes would require in the order of
ONE BILLIONcomparisons.
2 Basic Assumptions
2 Basic Assumptions
• Two components of the same class will generate similar trees and two components of different classes will generate different trees.
2 Basic Assumptions
• Two components of the same class will generate similar trees and two components of different classes will generate different trees.
• It is possible to provide a unique key for elements that is stable across different renders.
Pair-wise Diff Different Node Types
renderA: <div />renderB: <span />=> [removeNode <div />], [insertNode <span />]
Code
renderA: <Header />renderB: <Content />=> [removeNode <Header />], [insertNode <Content />]
Code
Pair-wise Diff DOM Nodes
renderA: <div id="before" />renderB: <div id="after" />=> [replaceAttribute id "after"]
Code
renderA: <div style={{color: 'red'}} />renderB: <div style={{fontWeight: 'bold'}} />=> [removeStyle color], [addStyle font-weight 'bold']
Code
List-wise Diff Problematic Case
renderA: <div><span>first</span></div>renderB: <div><span>first</span><span>second</span></div>=> [insertNode <span>second</span>]
Code
renderA: <div><span>first</span></div>renderB: <div><span>second</span><span>first</span></div>=> [replaceAttribute textContent 'second'], [insertNode <span>first</span>]
Code
List-wise Diff Problematic Case
renderA: <div><span>first</span></div>renderB: <div><span>first</span><span>second</span></div>=> [insertNode <span>second</span>]
Code
renderA: <div><span>first</span></div>renderB: <div><span>second</span><span>first</span></div>=> [replaceAttribute textContent 'second'], [insertNode <span>first</span>]
Code
Levenshtein DistanceO(n
2)
List-wise Diff Keys
renderA: <div><span key="first">first</span></div>renderB: <div><span key="second">second</span><span key="first">first</span></div>=> [insertNode <span>second</span>]
Code
If you specify a key, React is now able to find insertion, deletion, substitution and moves in O(n) using a hash table.
Trade-offs
Trade-offs• The algorithm will not try to match sub-trees of different
components classes. If you see yourself alternating between two components classes with very similar output, you may want to make it the same class. In practice, we haven't found this to be an issue.
Trade-offs• The algorithm will not try to match sub-trees of different
components classes. If you see yourself alternating between two components classes with very similar output, you may want to make it the same class. In practice, we haven't found this to be an issue.
• If you don't provide stable keys (by using Math.random() for example), all the sub-trees are going to be re-rendered every single time. By giving the users the choice to choose the key, they have the ability to shoot themselves in the foot.
Where to go from here? & Acknowledgements
• Official Documentation: https://facebook.github.io/react/
• React’s diff algorithm: http://calendar.perfplanet.com/2013/diff/
• React Demystified: http://blog.reverberate.org/2014/02/react-demystified.html
Thanks