Ререндер компонентів
1. Кожен компонент має свій "render effect"
Коли компонент монтується, Vue створює функцію рендера - ту, що перетворює реактивні дані на віртуальний DOM.
Ця функція огортається в реактивний ефект (ReactiveEffect).
effect(() => {
// render component template
vnode = renderComponent()
})Цей ефект працює як спостерігач: коли він викликається, Vue запам'ятовує, які реактивні властивості були "прочитані" під час рендеру.
2. Відстеження залежностей (track)
Коли в шаблоні використовується, наприклад:
<p>{{ user.name }}</p>При першому рендері відбувається таке:
- Vue звертається до
user.name. - Ця властивість - реактивна, обгорнута в
Proxy. - Пастка
getвсередині Proxy викликаєtrack(target, key). track()реєструє залежність:
targetMap = WeakMap {
user -> Map {
name -> Set(effectRenderComponent)
}
}Тепер Vue знає, що компонент залежить від user.name.
3. Коли дані змінюються (trigger)
Коли значення змінюється:
user.name = 'Alex'Vue перехоплює це через пастку set і викликає:
trigger(user, 'name')Тепер trigger():
- Знаходить усі ефекти, які залежать від
user.name(у нашому випадку -render effectкомпонента). - Ставить ефект у чергу оновлення.
4. Оновлення лише потрібних компонентів
У черзі може бути багато ефектів, але Vue виконує лише ті, що залежать від зміненої властивості.
- Змінився
user.name-> оновлюється лише компонент, де він використовується. - Змінився
count-> оновлюється лише компонент, що використовуєcount. - Решта компонентів залишаються незмінними.
Це і є гранулярна реактивність: Vue не робить "глобальний ререндер", а точково оновлює лише потрібні гілки дерева компонентів.
5. Як Vue уникає зайвих перерендерів
Vue 3 робить це дуже розумно:
- Компоненти мають прапорці оновлення (dirty flags).
- Якщо дані не змінилися (
oldValue === newValue), перемальовування не відбувається. - Vue батчить (batching) оновлення: усі зміни в одному тіку об'єднуються і виконуються асинхронно в "microtask queue" (через
Promise.resolve()).
Це означає, що якщо за одну подію змінилося 10 реактивних властивостей - Vue все перерахує один раз, а не 10.
6. Оновлення за "реактивним деревом"
Можна уявити систему залежностей як реактивне дерево:
Reactive data (ref, reactive)
└── Computed values
└── Watchers / render effects
└── Components → Virtual DOM → Real DOMКоли Vue викликає trigger(), оновлення йде по гілці дерева, а не по всьому застосунку.
Якщо змінилася властивість user.age, Vue не торкнеться компонентів, що використовують user.name.
7. Просте пояснення людськими словами
Коли компонент рендериться, Vue "слухає", які дані він використовує.
Потім, коли ці дані змінюються, Vue "дзвонить" лише тим компонентам, які на них підписані.
Все інше - не чіпає.
8. Коротке резюме
| Етап | Що відбувається |
|---|---|
| 1. Рендер | Компонент звертається до реактивних даних -> Vue відстежує залежності через track() |
| 2. Зміна даних | Proxy викликає trigger() для змінених властивостей |
| 3. Пошук ефектів | Vue знаходить компоненти, залежні від цих даних |
| 4. Черга оновлень | Ефекти потрапляють у чергу (batch updates) |
| 5. Повторний рендер | Перемальовуються лише потрібні компоненти |
9. Візуальна аналогія
Компонент "UserCard"
├── залежить від user.name
└── залежить від user.age
Компонент "PostCard"
└── залежить від post.title
Змінився user.name -> перемалюється лише UserCardКоротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.