Component re-rendering
1. Each component has its own "render effect"
When a component mounts, Vue creates a render function - the one that turns reactive data into a virtual DOM.
This function is wrapped in a reactive effect (ReactiveEffect).
effect(() => {
// render component template
vnode = renderComponent()
})This effect works like an observer: when it runs, Vue remembers which reactive properties were "read" during the render.
2. Dependency tracking (track)
When the template uses, for example:
<p>{{ user.name }}</p>On the first render, the following happens:
- Vue accesses
user.name. - This property is reactive, wrapped in a
Proxy. - The
gettrap inside the Proxy callstrack(target, key). track()registers the dependency:
targetMap = WeakMap {
user -> Map {
name -> Set(effectRenderComponent)
}
}Now Vue knows the component depends on user.name.
3. When the data changes (trigger)
When the value changes:
user.name = 'Alex'Vue intercepts this through the set trap and calls:
trigger(user, 'name')Now trigger():
- Finds all effects that depend on
user.name(in our case, the component'srender effect). - Puts the effect in the update queue.
4. Updating only the components that need it
The queue can hold many effects, but Vue runs only the ones that depend on the changed property.
user.namechanged -> only the component where it is used updates.countchanged -> only the component usingcountupdates.- The rest of the components remain untouched.
This is granular reactivity: Vue does not do a "global re-render", it precisely updates only the branches of the component tree that need it.
5. How Vue avoids unnecessary re-renders
Vue 3 does this very smartly:
- Components have update flags (dirty flags).
- If the data has not changed (
oldValue === newValue), no re-render happens. - Vue batches updates: all changes within one tick are combined and run asynchronously in the "microtask queue" (via
Promise.resolve()).
This means that if 10 reactive properties change during a single event, Vue recalculates everything once, not 10 times.
6. Updates along the "reactive tree"
You can picture the dependency system as a reactive tree:
Reactive data (ref, reactive)
└── Computed values
└── Watchers / render effects
└── Components → Virtual DOM → Real DOMWhen Vue calls trigger(), the update travels along a branch of the tree, not through the whole application.
If the user.age property changes, Vue does not touch components that use user.name.
7. A simple explanation in plain words
When a component renders, Vue "listens" to which data it uses.
Then, when that data changes, Vue "calls" only the components that are subscribed to it.
Everything else is left untouched.
8. Quick summary
| Stage | What happens |
|---|---|
| 1. Render | The component accesses reactive data -> Vue tracks dependencies via track() |
| 2. Data change | The Proxy calls trigger() for the changed properties |
| 3. Finding effects | Vue finds the components that depend on that data |
| 4. Update queue | Effects land in the queue (batch updates) |
| 5. Re-render | Only the necessary components re-render |
9. Visual analogy
Component "UserCard"
├── depends on user.name
└── depends on user.age
Component "PostCard"
└── depends on post.title
user.name changed -> only UserCard re-rendersShort Answer
Interview readyA concise answer to help you respond confidently on this topic during an interview.