
Security News
Meet Socket at Black Hat and DEF CON 2025 in Las Vegas
Meet Socket at Black Hat & DEF CON 2025 for 1:1s, insider security talks at Allegiant Stadium, and a private dinner with top minds in software supply chain security.
vue-lazy-hydration
Advanced tools
Lazy Hydration of Server-Side Rendered Vue.js Components
Lazy Hydration of Server-Side Rendered Vue.js Components
vue-lazy-hydration
is a renderless Vue.js component to improve Estimated Input Latency and Time to Interactive of server-side rendered Vue.js applications. This can be achieved by using lazy hydration to delay the hydration of pre-rendered HTML.
npm install vue-lazy-hydration
import LazyHydrate from 'vue-lazy-hydration';
// ...
export default {
// ...
components: {
LazyHydrate,
// ...
},
// ...
};
In the example below you can see the four hydration modes in action.
<template>
<div class="ArticlePage">
<LazyHydrate when-idle>
<ImageSlider/>
</LazyHydrate>
<LazyHydrate never>
<ArticleContent :content="article.content"/>
</LazyHydrate>
<LazyHydrate when-visible>
<AdSlider/>
</LazyHydrate>
<!-- `on-interaction` listens for a `focus` event by default ... -->
<LazyHydrate on-interaction>
<CommentForm :article-id="article.id"/>
</LazyHydrate>
<!-- ... but you can listen for any event you want ... -->
<LazyHydrate on-interaction="click">
<CommentForm :article-id="article.id"/>
</LazyHydrate>
<!-- ... or even multiple events. -->
<LazyHydrate :on-interaction="['click', 'touchstart']">
<CommentForm :article-id="article.id"/>
</LazyHydrate>
</div>
</template>
<script>
import LazyHydrate from 'vue-lazy-hydration';
export default {
components: {
LazyHydrate,
AdSlider: () => import('./AdSlider.vue'),
ArticleContent: () => import('./ArticleContent.vue'),
CommentForm: () => import('./CommentForm.vue'),
ImageSlider: () => import('./ImageSlider.vue'),
},
// ...
};
</script>
ImageSlider
should be hydrated eventually, but we can wait until the browser is idle.ArticleContent
component is never hydrated on the client, which also means it will never be interactive (static content only).AdSlider
beneath the article content, this component will most likely not be visible initially so we can delay hydration until the point it becomes visible.CommentForm
but because most people only read the article and don't leave a comment, we can save resources by only hydrating the component whenever it actually receives focus.Sometimes you might want to prevent a component from loading initially but you want to activate it on demand if a certain action is triggered. You can do this by manually triggering the component to hydrate like you can see in the following example.
<template>
<div class="MyComponent">
<button @click="editModeActive = true">
Activate edit mode
</button>
<LazyHydrate never :trigger-hydration="editModeActive">
<UserSettingsForm/>
</LazyHydrate>
</div>
</template>
<script>
import LazyHydrate from 'vue-lazy-hydration';
export default {
components: {
LazyHydrate,
UserSettingsForm: () => import('./UserSettingsForm.vue'),
},
data() {
return {
editModeActive: false,
};
},
// ...
};
</script>
Because of how this package works, it is not possible to nest multiple root nodes inside of a single <LazyHydrate>
. But you can wrap multiple components with a <div>
.
<template>
<div class="MyComponent">
<LazyHydrate never>
<div>
<ArticleHeader/>
<ArticleContent/>
<ArticleMetaInfo/>
<ArticleFooter/>
</div>
</LazyHydrate>
</div>
</template>
Internally the Intersection Observer API is used to determine if a component is visible or not. You can provide Intersection Observer options to the when-visible
property to configure the Intersection Observer.
<template>
<div class="MyComponent">
<LazyHydrate :when-visible="{ rootMargin: '100px' }">
<ArticleFooter/>
</LazyHydrate>
</div>
</template>
For a list of possible options please take a look at the Intersection Observer API documentation on MDN.
Additionally to the <LazyHydrate>
wrapper component you can also use Import Wrappers to lazy load and hydrate certain components.
<template>
<div class="ArticlePage">
<ImageSlider/>
<ArticleContent :content="article.content"/>
<AdSlider/>
<CommentForm :article-id="article.id"/>
</div>
</template>
<script>
import {
hydrateOnInteraction,
hydrateNever,
hydrateWhenIdle,
hydrateWhenVisible,
} from 'vue-lazy-hydration';
export default {
components: {
AdSlider: hydrateWhenVisible(
() => import('./AdSlider.vue'),
// Optional.
{ observerOptions: { rootMargin: '100px' } },
),
ArticleContent: hydrateNever(() => import('./ArticleContent.vue')),
CommentForm: hydrateOnInteraction(
() => import('./CommentForm.vue'),
// `focus` is the default event.
{ event: 'focus' },
),
ImageSlider: hydrateWhenIdle(() => import('./ImageSlider.vue')),
},
// ...
};
</script>
This plugin will not work as advertised if you're not using it in combination with SSR. Although it should work with every pre-rendering approach (like Prerender SPA Plugin, Gridsome, ...) I've only tested it with Nuxt.js so far.
Breaking changes:
ssr-only
was renamed to never
(as in "Hydrate this? Never!").-<LazyHydrate ssr-only>
+<LazyHydrate never>
<ArticleContent/>
</LazyHydrate>
ignored-props
on Import Wrappers is not necessary anymore. components: {
- ArticleContent: hydrateNever(() => import('./ArticleContent.vue'), { ignoredProps: ['content'] }),
+ ArticleContent: hydrateNever(() => import('./ArticleContent.vue')),
}
The code of the v1 version of this package was based on a similar package created by Rahul Kadyan.
Because the core functionality of vue-lazy-hydration
heavily relies on browser APIs like IntersectionObserver
and requestIdleCallback()
, it is tough to write meaningful unit tests without having to write numerous mocks. Because of that, we mostly use integration tests and some performance benchmarks to test the functionality of this package.
Execute the following commands to run the integration tests:
npm run test:integration:build
npm run test:integration
Execute the following commands to run the performance benchmark:
npm run test:perf:build
npm run test:perf
Markus Oberlehner
Website: https://markus.oberlehner.net
Twitter: https://twitter.com/MaOberlehner
PayPal.me: https://paypal.me/maoberlehner
Patreon: https://www.patreon.com/maoberlehner
MIT
FAQs
Lazy Hydration of Server-Side Rendered Vue.js Components
The npm package vue-lazy-hydration receives a total of 15,997 weekly downloads. As such, vue-lazy-hydration popularity was classified as popular.
We found that vue-lazy-hydration demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Meet Socket at Black Hat & DEF CON 2025 for 1:1s, insider security talks at Allegiant Stadium, and a private dinner with top minds in software supply chain security.
Security News
CAI is a new open source AI framework that automates penetration testing tasks like scanning and exploitation up to 3,600× faster than humans.
Security News
Deno 2.4 brings back bundling, improves dependency updates and telemetry, and makes the runtime more practical for real-world JavaScript projects.