Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Lazy Hydration of Server-Side Rendered Vue.js Components

License

NotificationsYou must be signed in to change notification settings

maoberlehner/vue-lazy-hydration

 
 

Repository files navigation

PatreonDonateBuild StatusGitHub stars

Lazy Hydration of Server-Side Rendered Vue.js Components

ko-fi

vue-lazy-hydration is a renderless Vue.js component toimprove Estimated Input Latency and Time to Interactive of server-side rendered Vue.js applications. This can be achievedby using lazy hydration to delay the hydration of pre-rendered HTML.

Install

npm install vue-lazy-hydration
importLazyHydratefrom'vue-lazy-hydration';// ...exportdefault{// ...components:{    LazyHydrate,// ...},// ...};

Basic example

In the example below you can see the four hydration modes in action.

<template><divclass="ArticlePage"><LazyHydratewhen-idle><ImageSlider/></LazyHydrate><LazyHydratenever><ArticleContent:content="article.content"/></LazyHydrate><LazyHydratewhen-visible><AdSlider/></LazyHydrate><!-- `on-interaction` listens for a `focus` event by default ... --><LazyHydrateon-interaction><CommentForm:article-id="article.id"/></LazyHydrate><!-- ... but you can listen for any event you want ... --><LazyHydrateon-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>importLazyHydratefrom'vue-lazy-hydration';exportdefault{components:{    LazyHydrate,AdSlider:()=>import('./AdSlider.vue'),ArticleContent:()=>import('./ArticleContent.vue'),CommentForm:()=>import('./CommentForm.vue'),ImageSlider:()=>import('./ImageSlider.vue'),},// ...};</script>
  1. Because it is at the very top of the page, theImageSlider should be hydrated eventually, but we can wait until the browser is idle.
  2. TheArticleContent component is never hydrated on the client, which also means it will never be interactive (static content only).
  3. Next we can see theAdSlider beneath the article content, this component will most likely not be visible initially so we can delay hydration until the point it becomes visible.
  4. At the very bottom of the page we want to render aCommentForm 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.

Advanced

Manually trigger hydration

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><divclass="MyComponent"><button@click="editModeActive = true">      Activate edit mode</button><LazyHydratenever:trigger-hydration="editModeActive"><UserSettingsForm/></LazyHydrate></div></template><script>importLazyHydratefrom'vue-lazy-hydration';exportdefault{components:{    LazyHydrate,UserSettingsForm:()=>import('./UserSettingsForm.vue'),},data(){return{editModeActive:false,};},// ...};</script>

Multiple root nodes

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><divclass="MyComponent"><LazyHydratenever><div><ArticleHeader/><ArticleContent/><ArticleMetaInfo/><ArticleFooter/></div></LazyHydrate></div></template>

Intersection Observer options

Internally theIntersection Observer API is used to determine if a component is visible or not. You can provide Intersection Observer options to thewhen-visible property to configure the Intersection Observer.

<template><divclass="MyComponent"><LazyHydrate:when-visible="{ rootMargin: '100px' }"><ArticleFooter/></LazyHydrate></div></template>

For a list of possible options pleasetake a look at the Intersection Observer API documentation on MDN.

Import Wrappers

Additionally to the<LazyHydrate> wrapper component you can also use Import Wrappers to lazy load and hydrate certain components.

<template><divclass="ArticlePage"><ImageSlider/><ArticleContent:content="article.content"/><AdSlider/><CommentForm:article-id="article.id"/></div></template><script>import{hydrateOnInteraction,hydrateNever,hydrateWhenIdle,hydrateWhenVisible,}from'vue-lazy-hydration';exportdefault{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>

Benchmarks

Without lazy hydration

Without lazy hydration.

With lazy hydration

With lazy hydration.

Caveats

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 (likePrerender SPA Plugin,Gridsome, ...) I've only tested it withNuxt.js so far.

Upgrade v1.x to v2.x

Breaking changes:

  • ssr-only was renamed tonever (as in "Hydrate this? Never!").
-<LazyHydrate ssr-only>+<LazyHydrate never>   <ArticleContent/> </LazyHydrate>
  • Specyfingignored-props on Import Wrappers is not necessary anymore.
 components: {-  ArticleContent: hydrateNever(() => import('./ArticleContent.vue'), { ignoredProps: ['content'] }),+  ArticleContent: hydrateNever(() => import('./ArticleContent.vue')), }

Articles

Credits

The code of the v1 version of this package was based on asimilar package created byRahul Kadyan.

Testing

Because the core functionality ofvue-lazy-hydration heavily relies on browser APIs likeIntersectionObserver andrequestIdleCallback(), 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.

Integration tests

Execute the following commands to run the integration tests:

npm run test:integration:buildnpm run test:integration

Performance tests

Execute the following commands to run the performance benchmark:

npm run test:perf:buildnpm run test:perf

About

Author

Markus Oberlehner
Website:https://markus.oberlehner.net
Twitter:https://twitter.com/MaOberlehner
PayPal.me:https://paypal.me/maoberlehner
Patreon:https://www.patreon.com/maoberlehner

License

MIT

About

Lazy Hydration of Server-Side Rendered Vue.js Components

Topics

Resources

License

Code of conduct

Contributing

Stars

Watchers

Forks

Packages

No packages published

[8]ページ先頭

©2009-2025 Movatter.jp