Deferred Hydration Strategies
hydrateOnIdle(), hydrateOnVisible(), hydrateOnInteraction() — Nuxt lazy hydration.
Deferred Hydration Strategies is a free Vue Academy lesson on CoddyKit. This is lesson 4 of 4. Any 3 lessons of this learning path are free to read in full — after that, CoddyKit PRO unlocks every lesson, plus hands-on practice with a built-in code editor and a 24/7 AI tutor. It is part of the Vue Academy learning path, and your progress syncs across the web and the CoddyKit app. The Vue Academy course includes 4 lessons in total.
The Hydration Cost Problem
SSR sends ready-to-view HTML, but the client still has to hydrate every component to make it interactive. Hydrating everything up front blocks the main thread and delays interactivity (TTI).
Deferred (lazy) hydration delays hydration of components until they are actually needed.
Nuxt Auto-Lazy Prefix
In Nuxt, prefixing a component with Lazy makes it lazily imported. Combined with hydration strategies, this defers both the JS download and the hydration work.
<template>
<!-- Nuxt resolves LazyMyComponent automatically -->
<LazyMyComponent />
</template>hydrateOnVisible
hydrateOnVisible hydrates a component only when it scrolls into the viewport, using an IntersectionObserver under the hood. Perfect for below-the-fold sections.
<template>
<!-- Nuxt syntax: hydrate when visible -->
<LazyProductReviews hydrate-on-visible />
</template>
<!-- core Vue equivalent -->
<!-- defineAsyncComponent({ hydrate: hydrateOnVisible() }) -->hydrateOnVisible with Margin
You can pass IntersectionObserver options so hydration starts slightly before the element is visible, smoothing the experience.
<template>
<!-- start hydrating 100px before entering viewport -->
<LazyComments
:hydrate-on-visible="{ rootMargin: '100px' }"
/>
</template>hydrateOnIdle
hydrateOnIdle waits for the browser to be idle (via requestIdleCallback) before hydrating. Use it for non-critical widgets that should not compete with initial interactivity.
<template>
<!-- hydrate during idle time -->
<LazyNewsletterSignup hydrate-on-idle />
<!-- optional max timeout in ms -->
<LazyChatBubble :hydrate-on-idle="3000" />
</template>hydrateOnInteraction
hydrateOnInteraction defers hydration until a specified DOM event fires on the element (click, focus, mouseover). The component stays static HTML until the user engages.
<template>
<!-- hydrate only on click -->
<LazyDropdownMenu hydrate-on-interaction="click" />
<!-- multiple events -->
<LazyTooltip :hydrate-on-interaction="['focus', 'mouseover']" />
</template>hydrateOnMediaQuery
hydrateOnMediaQuery hydrates only when a media query matches — for example, hydrating a desktop-only sidebar that is hidden on mobile, avoiding wasted work on small screens.
<template>
<!-- only hydrate on wide screens -->
<LazyDesktopSidebar
hydrate-on-media-query="(min-width: 1024px)"
/>
</template>Core Vue API: hydrate helpers
Outside Nuxt, the same strategies exist as hydration helpers passed to defineAsyncComponent's hydrate option. The Nuxt prefixes are sugar over these.
import { defineAsyncComponent, hydrateOnVisible } from 'vue'
const LazyChart = defineAsyncComponent({
loader: () => import('./Chart.vue'),
hydrate: hydrateOnVisible()
})Choosing the Right Strategy
Match strategy to intent:
- Visible — below-the-fold content (reviews, footers)
- Idle — background widgets (analytics, newsletter)
- Interaction — UI revealed by user action (menus, modals)
- Media query — device-specific UI
Trade-offs to Watch
Deferred hydration improves TTI but means the component is not interactive until its trigger fires. For interaction-based strategies, the very first click is consumed to trigger hydration and may feel slightly delayed. Reserve eager hydration for primary call-to-action UI.
Combining with Islands
Deferred hydration pairs with the islands architecture: most of the page is static server-rendered HTML, and only interactive islands hydrate — lazily, by strategy. The result is minimal client JS and fast interactivity where it matters.
<template>
<StaticArticle /> <!-- never hydrates -->
<LazyCommentBox hydrate-on-visible />
<LazyLikeButton hydrate-on-interaction="click" />
</template>Quick Check
Test your understanding of hydration strategies.
Recap
You learned deferred hydration:
- Nuxt's
Lazyprefix lazily imports components - hydrateOnVisible — below-fold via IntersectionObserver
- hydrateOnIdle — non-critical, during idle time
- hydrateOnInteraction — event-triggered (click/focus)
- Core Vue exposes these as
hydratehelpers ondefineAsyncComponent
Learn HTML with an AI tutor — free
Write and run real code in your browser, get instant help from a 24/7 AI tutor, and pick up where you left off on the web or in the app.
- Courses
- 42
- Lessons
- 156
Frequently Asked Questions
Is the “Deferred Hydration Strategies” lesson free?
Yes — any 3 lessons of the Vue Academy learning path, including “Deferred Hydration Strategies”, are free to read in full here on the web. After that, CoddyKit PRO unlocks every lesson, plus interactive practice with a built-in code editor and a 24/7 AI tutor. The Vue Academy course includes 4 lessons in total.
What will I learn in “Deferred Hydration Strategies”?
hydrateOnIdle(), hydrateOnVisible(), hydrateOnInteraction() — Nuxt lazy hydration. You practise Vue Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start Vue Academy?
No prior experience is required. Vue Academy on CoddyKit is structured for beginners through advanced learners, so you can start here or from the beginning and move at your own pace. This is lesson 4 of 4.
How long does the “Deferred Hydration Strategies” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this Vue Academy lesson?
Yes. Every Vue Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- Vue Suspense Component
- Async Components with defineAsyncComponent
- Streaming SSR with renderToWebStream
- Deferred Hydration Strategies