Vue3 Compilation Optimization: Dynamic Node Collection and PatchFlag Collaboration Principle
Description
Vue3's compilation optimization achieves targeted updates through the collaborative work of dynamic node collection and PatchFlag. During the template compilation phase, the compiler analyzes dynamic parts within the template (such as dynamic attributes, dynamic text), marks each dynamic node with a PatchFlag (patch flag), and collects these dynamic nodes into a Block. During updates, PatchFlags are used to quickly identify the type of node changes, allowing for comparison of only the dynamic content and skipping the comparison of static nodes, thereby improving diff efficiency.
Process
-
Template Compilation Phase: Analyze Dynamic Bindings
- When parsing the template, the compiler identifies dynamic content, such as
{{ text }}(dynamic text),:class="cls"(dynamic attribute),v-if(dynamic structure). - For each dynamic node, a unique PatchFlag value is assigned based on its dynamic type (e.g.,
1for text dynamic,2for class dynamic). - Example:
After compilation, the<div :class="cls">{{ text }}</div>divnode is marked with a PatchFlag of3(1 | 2, a bitwise OR combination of text and class dynamics).
- When parsing the template, the compiler identifies dynamic content, such as
-
Dynamic Node Collection and Block Generation
- The compiler defines root nodes and nodes wrapped by
v-if/v-foras a Block. - A Block collects all dynamic child nodes within it (including nested dynamic nodes), forming a dynamic node array (
dynamicChildren). - Static nodes are not collected into
dynamicChildrenand are skipped during updates. - Example:
After compilation, the<div> <span>{{ a }}</span> <p>Static Text</p> <span>{{ b }}</span> </div>divacts as a Block. ItsdynamicChildrencontains only the two dynamicspannodes, and the staticpnode is excluded.
- The compiler defines root nodes and nodes wrapped by
-
PatchFlag's Collaborative Role in the Update Phase
- When a component updates, the renderer compares the old and new virtual DOM trees.
- For Block nodes, it directly traverses their
dynamicChildrenarray, comparing only the dynamic nodes, without needing to recursively traverse the entire subtree. - Based on each dynamic node's PatchFlag, targeted updates are performed:
- If the PatchFlag includes text dynamics (
1), only the node'stextContentis updated. - If it includes class dynamics (
2), only theclassattribute is updated. - Bitwise AND operations (e.g.,
flag & 1) are used to quickly determine the update type.
- If the PatchFlag includes text dynamics (
- Example:
If the value ofain the abovedivchanges, the renderer directly finds the firstspannode and, based on its PatchFlag (1), updates only its text content, skipping the comparison of the staticpand the secondspan.
-
Performance Optimization Impact
- Through dynamic node collection, the scope of Diff is reduced from the entire tree to a list of dynamic nodes, lowering the time complexity from O(n) to O(number of dynamic nodes).
- PatchFlag refines the update logic, avoiding unnecessary attribute or text comparisons and reducing JavaScript execution overhead.
- Combined with other optimizations like static hoisting (where static nodes are hoisted outside the render function), overall rendering performance is significantly improved.
Summary
The collaboration between dynamic node collection and PatchFlag is at the core of Vue3's compilation optimization. By analyzing and marking dynamic content at compile time and performing targeted updates at runtime, it minimizes the cost of the Diff process, implementing an efficient re-rendering mechanism.