From 261c8b111d046204bd22392a8b920e3c3d4def48 Mon Sep 17 00:00:00 2001 From: Michael Brevard Date: Wed, 7 Aug 2024 07:06:15 +0300 Subject: [PATCH] feat(hydration): allow fine tuning of lazy hydration strategy triggers (#11530) --- .../runtime-core/src/hydrationStrategies.ts | 47 +++++++++---------- .../e2e/hydration-strat-visible.html | 2 +- 2 files changed, 23 insertions(+), 26 deletions(-) diff --git a/packages/runtime-core/src/hydrationStrategies.ts b/packages/runtime-core/src/hydrationStrategies.ts index 4f0a2d23e1a..57b543b4640 100644 --- a/packages/runtime-core/src/hydrationStrategies.ts +++ b/packages/runtime-core/src/hydrationStrategies.ts @@ -15,35 +15,32 @@ export type HydrationStrategy = ( forEachElement: (cb: (el: Element) => any) => void, ) => (() => void) | void -export type HydrationStrategyFactory = ( +export type HydrationStrategyFactory = ( options?: Options, ) => HydrationStrategy -export const hydrateOnIdle: HydrationStrategyFactory = () => hydrate => { - const id = requestIdleCallback(hydrate) - return () => cancelIdleCallback(id) -} - -export const hydrateOnVisible: HydrationStrategyFactory = - (margin = 0) => - (hydrate, forEach) => { - const ob = new IntersectionObserver( - entries => { - for (const e of entries) { - if (!e.isIntersecting) continue - ob.disconnect() - hydrate() - break - } - }, - { - rootMargin: isString(margin) ? margin : margin + 'px', - }, - ) - forEach(el => ob.observe(el)) - return () => ob.disconnect() +export const hydrateOnIdle: HydrationStrategyFactory = + (timeout = 10000) => + hydrate => { + const id = requestIdleCallback(hydrate, { timeout }) + return () => cancelIdleCallback(id) } +export const hydrateOnVisible: HydrationStrategyFactory< + IntersectionObserverInit +> = opts => (hydrate, forEach) => { + const ob = new IntersectionObserver(entries => { + for (const e of entries) { + if (!e.isIntersecting) continue + ob.disconnect() + hydrate() + break + } + }, opts) + forEach(el => ob.observe(el)) + return () => ob.disconnect() +} + export const hydrateOnMediaQuery: HydrationStrategyFactory = query => hydrate => { if (query) { @@ -58,7 +55,7 @@ export const hydrateOnMediaQuery: HydrationStrategyFactory = } export const hydrateOnInteraction: HydrationStrategyFactory< - string | string[] + keyof HTMLElementEventMap | Array > = (interactions = []) => (hydrate, forEach) => { diff --git a/packages/vue/__tests__/e2e/hydration-strat-visible.html b/packages/vue/__tests__/e2e/hydration-strat-visible.html index 863455c8450..6420ca9fe4f 100644 --- a/packages/vue/__tests__/e2e/hydration-strat-visible.html +++ b/packages/vue/__tests__/e2e/hydration-strat-visible.html @@ -35,7 +35,7 @@ const AsyncComp = defineAsyncComponent({ loader: () => Promise.resolve(Comp), - hydrate: hydrateOnVisible(rootMargin + 'px') + hydrate: hydrateOnVisible({rootMargin: rootMargin + 'px'}) }) createSSRApp({