[Vue] Vue 3.5 Lazy Hydration

Lazy hydration has been implemented as part of the Vue’s Async Component API.

So before we get to lazy hydration, let’s take a quick look at async component.

An async component enables lazy loading, meaning the component’s code is downloaded from the server only when needed for rendering. This improves initial page load times by reducing the amount of code that must be loaded upfront.

To create an async component, we have to first create a regular component:

📁 /components/MyComponent.vue

<template>
  <p>This is a component.</p>
</template>

Next, create another component without the .vue extension, export a component created thedefineAsyncfunction, and set the loader option to use the regular component.

📁 /components/MyAsyncComponent.vue

import { defineAsyncComponent } from "vue"

export default defineAsyncComponent({
  loader: () => import('./MyComponent.vue')
})

This creates an async component that lazy-loads the original component, essentially acting as a wrapper around it.

When we want to use this component, we just need to import and use it just like other components.

📁 /pages/index.vue

<script setup lang="ts">
import MyAsyncComponent from '@/components/MyLazyComponent.vue'
</script>>

<template>
  <MyAsyncComponent />
</template>

Since I’m demoing this in a Nuxt.js app, I don’t have to import it, Nuxt.js will auto-import anything from the components folder.

📁 /pages/index.vue

<script setup lang="ts">
</script>

<template>
  <MyAsyncComponent />
</template>

The reason why I’m using Nuxt.js instead of just Vue.js is because it’s easier to demo SSR-related features with a Nuxt.js app.

That covers async components and lazy loading. Next, let’s explore lazy hydration.

Here’s a quick refresher: Hydration is a client-side step in server-side rendering. First, the component is rendered on the server to produce the HTML. Then, when both the HTML and component code reach the client side, the component renders again to become fully interactive. This second client-side rendering is called “hydration” because it takes the existing HTML and “hydrates” it by running the component code again.

Lazy hydration is basically delaying this hydration step. This could be a good idea if the hydration process is making the initial load of the page slow.

All you have to do is to import a hydration strategy such as hydrateOnInteration, and use it with the hydrate option in the async component.

📁 /components/MyLazyComponent.vue

import { defineAsyncComponent, hydrateOnInteraction } from "vue"

export default defineAsyncComponent({
  loader: () => import('./MyComponent.vue'),
  hydrate: hydrateOnInteraction('mouseover')
})

There are also a few other built-in strategies: hydrateOnVisiblehydrateOnIdle, and hydrateOnMediaQuery.

We’re using the hydrateOnInteration strategy here. This means this component will only start hydration when it’s being interacted with. With this strategy, we can choose which interactive event should trigger the hydration, for example, a click, or a mouseover.

To test this, let’s put a console log message in the original component:

📁 /components/MyComponent.vue

<script setup lang="ts">
console.log('running MyComponent.vue')
</script>

<template>
  <p>This is a component.</p>
</template>

When this page is loaded, we’ll see console log message from the first rendering on the server side. We don’t see the client-side message here because this component hasn’t been hydrated yet.

Let’s mouse over the component. This will trigger the hydration for the LazyComponent and you’ll see the client-side message.

That’s it for lazy hydration from Vue 3.5. If you want to learn more about async component and lazy hydration, you can check out the official documentation.


Code

📁 /components/MyComponent.vue

<script setup lang="ts">
console.log('running MyComponent.vue')
</script>

<template>
  <p>This is a component.</p>
</template>

📁 /components/MyAsyncComponent.ts

import { defineAsyncComponent, hydrateOnInteraction } from "vue"

export default defineAsyncComponent({
  loader: () => import('./MyComponent.vue'),
  hydrate: hydrateOnInteraction('mouseover')
})

📁 /pages/index.vue

<script setup lang="ts">
</script>

<template>
  <MyAsyncComponent />
</template>
posted @ 2025-03-13 15:11  Zhentiw  阅读(55)  评论(0)    收藏  举报