Skip to main content

Ререндер компонентів

1. Кожен компонент має свій "render effect"

Коли компонент монтується, Vue створює функцію рендера - ту, що перетворює реактивні дані на віртуальний DOM. Ця функція огортається в реактивний ефект (ReactiveEffect).

javascript
effect(() => { // render component template vnode = renderComponent() })

Цей ефект працює як спостерігач: коли він викликається, Vue запам'ятовує, які реактивні властивості були "прочитані" під час рендеру.


2. Відстеження залежностей (track)

Коли в шаблоні використовується, наприклад:

javascript
<p>{{ user.name }}</p>

При першому рендері відбувається таке:

  1. Vue звертається до user.name.
  2. Ця властивість - реактивна, обгорнута в Proxy.
  3. Пастка get всередині Proxy викликає track(target, key).
  4. track() реєструє залежність:
javascript
targetMap = WeakMap { user -> Map { name -> Set(effectRenderComponent) } }

Тепер Vue знає, що компонент залежить від user.name.


3. Коли дані змінюються (trigger)

Коли значення змінюється:

javascript
user.name = 'Alex'

Vue перехоплює це через пастку set і викликає:

javascript
trigger(user, 'name')

Тепер trigger():

  1. Знаходить усі ефекти, які залежать від user.name (у нашому випадку - render effect компонента).
  2. Ставить ефект у чергу оновлення.

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. Оновлення за "реактивним деревом"

Можна уявити систему залежностей як реактивне дерево:

javascript
Reactive data (ref, reactive) └── Computed values └── Watchers / render effects └── ComponentsVirtual DOMReal 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. Візуальна аналогія

javascript
Компонент "UserCard" ├── залежить від user.name └── залежить від user.age Компонент "PostCard" └── залежить від post.title Змінився user.name -> перемалюється лише UserCard

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.