Vdom solves three problems
- Efficient diff algorithm
- Just update the DOM nodes that need to be updated
- Data change monitoring, batch DOM read and write operations
The diff algorithm
- Recursive: O (n ^ 3)
- react vdom diff O(n)
The diff strategy
- It rarely crosses layers, so we compare layers, not layers
- The same Component has the same tree structure, and different components have different tree structures
- The child node of the same level, key
Corresponding to tree DIff, Component Diff, element Diff
tree diff
UpdateDepth: Controls the dom tree level
Q: If there is movement across hierarchies, how should it be handled?
Create and then delete the corresponding one
component diff
- same component
- Different Component, dirty Component, replaces all child nodes
- shouldComponentUpdate()
element diff
- insert_markup, move_existing, delete_node
move_existing
GenerateComponentChildren call receiveComponent, prev = next
from: A, B, C, D
to: B, A, D, C
key
for.. In traverses the new one gets the key, goes to the old one and moves if it exists, before moving
Lastindex, order optimization: If the new node is larger than the old lastIndex, it is new
conclusion
- O(n^3)=> O(n)
- Avoid moving the last element to the front
- Compare tree diff by layer
- Component diff tree diff
- key => element diff
- Suggestion: Develop components to stabilize dom structure and improve performance
- Suggestion: Avoid inserting end-of-line elements directly to the front
- ShouldCompoentUpdate should do diff
Snabbdom github library (vue2.0)
Two – end comparison algorithm
Inferno. Js claims the fastest Diff algorithm (borrowed from Vue3.0)
Abcd dABC only moves D, while React requires ABC to move, which is why React is poorly designed
scheduling
fiber
- Vdom layer
- The Reconciler layer does some dom Diff lifecycle hooks with some sophisticated arithmetic
- Render layer reactDOM, RN
It’s just gonna help you make some slices
At setState, start coordinating, traverse your VDOM, go to diff, get the real DOM, and then pass it to Render
time slice
requestIdleCallback && requestAnimationFrame
- RequestIdleCallback: called when the browser is idle, the callback does not have to be executed
A normal browser does these things in a frame:
- Touch,wheel blocking input event === click, keypress non-blocking input event
- Timers Js performs
- Begin Frame (Window resize, Scroll, MediaQuery change, animation Events)
- RAF (requestAnimationFrame Callbacks, Intersection Observer Callbacks) calls
- Layout (1. Recalc style 2. Update Layout 3.
- Paint(1. Compositing Update 2. Paint Invilidation 3. Record)
IdleCallBack Execution position
input => rAF => frame commit => idle period(idleCallback,idleCallback) => input… cycle
React Fiber Reconciler
- Calculate task time(expirationTime)
- RequestIdleCallback polyfill version
MessageChannel
Macro tasks are executed first after rendering
RequestAnimationFrame resolves multiple times (which can be replaced by setTimeout if not executed in the background) + calculates the frame time and the next frame time + messageChannel
expirationTime
Current time (performance.now()) + constant (Task priority)