У SSR сторінка приходить готовим HTML, але інтерактивною стає лише після гідрації - коли Vue пройде по всіх компонентах сторінки й прив'яже обробники. На важких сторінках це секунди роботи головного потоку, за які кліки не працюють і погіршується INP.
Лінива гідрація (Vue 3.5+) дозволяє гідрувати асинхронні компоненти не одразу, а за умовою. Поки компонент не гідровано, він показує серверний HTML - вміст видно, просто без інтерактивності.
import { defineAsyncComponent, hydrateOnVisible, hydrateOnIdle, hydrateOnInteraction } from 'vue'
const Comments = defineAsyncComponent({
loader: () => import('./Comments.vue'),
hydrate: hydrateOnVisible(), // коли з'явиться в області видимості
})
const Footer = defineAsyncComponent({
loader: () => import('./Footer.vue'),
hydrate: hydrateOnIdle(), // коли браузер вільний
})
const Rating = defineAsyncComponent({
loader: () => import('./Rating.vue'),
hydrate: hydrateOnInteraction(['click', 'focus']), // при першій взаємодії
})
Стратегії:
hydrateOnIdle(timeout?)- черезrequestIdleCallback;hydrateOnVisible(options?)- черезIntersectionObserver(можна задатиrootMargin);hydrateOnMediaQuery('(max-width: 500px)')- лише якщо виконується медіазапит;hydrateOnInteraction(events)- при першій події; подія, що спричинила гідрацію, відтворюється після неї, тож клік не губиться;- власна стратегія - функція, що отримує
hydrateі повертає функцію прибирання.
Що це дає:
- головний потік вільний раніше - сторінка відповідає на дії швидше;
- код компонента може завантажитися лише тоді, коли він знадобиться (з динамічним
import()); - нижня частина довгих сторінок не займає час на старті.
Обмеження й ризики:
- працює лише з SSR і асинхронними компонентами; у звичайному SPA гідрації немає;
- до гідрації компонент не реагує - якщо користувач клікне на кнопку з
hydrateOnVisibleраніше, ніж та гідрується, клік не спрацює (на відміну відhydrateOnInteraction); - стан, що залежить від інших компонентів, - компонент, гідрований пізніше, не бачив попередніх подій;
- Nuxt має власні обгортки над цими стратегіями (
hydrate-on-visibleтощо) для компонентів з префіксомLazy.
Підхід схожий на «острівці» (Astro): інтерактивність вмикається лише там і тоді, де вона потрібна.
Докладніше в документації: Асинхронні компоненти: лінива гідрація