Skip to content

feat: lazy hydration strategies for async components #11458

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Jul 31, 2024
Merged
Prev Previous commit
Next Next commit
wip: layout hydration strategies
  • Loading branch information
yyx990803 committed Jul 25, 2024
commit 669c417ef433c184acbd9d80bb75c846fcae8384
12 changes: 6 additions & 6 deletions packages/runtime-core/src/apiAsyncComponent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,14 @@ import { ErrorCodes, handleError } from './errorHandling'
import { isKeepAlive } from './components/KeepAlive'
import { queueJob } from './scheduler'
import { markAsyncBoundary } from './helpers/useId'
import type { HydrationStrategy } from './hydrationStrategies'

export type AsyncComponentResolveResult<T = Component> = T | { default: T } // es modules

export type AsyncComponentLoader<T = any> = () => Promise<
AsyncComponentResolveResult<T>
>

type HydrationStrategy = (doHydrate: () => void) => void

export interface AsyncComponentOptions<T = any> {
loader: AsyncComponentLoader<T>
loadingComponent?: Component
Expand Down Expand Up @@ -57,7 +56,7 @@ export function defineAsyncComponent<
loadingComponent,
errorComponent,
delay = 200,
// hydrate,
hydrate: hydrateStrategy,
timeout, // undefined = never times out
suspensible = true,
onError: userOnError,
Expand Down Expand Up @@ -122,11 +121,12 @@ export function defineAsyncComponent<

__asyncLoader: load,

__asyncHydrate(instance, hydrate) {
__asyncHydrate(el, instance, hydrate) {
const doHydrate = hydrateStrategy ? hydrateStrategy(el, hydrate) : hydrate
if (resolvedComp) {
hydrate()
doHydrate()
} else {
load().then(() => !instance.isUnmounted && hydrate())
load().then(() => !instance.isUnmounted && doHydrate())
}
},

Expand Down
1 change: 1 addition & 0 deletions packages/runtime-core/src/componentOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,7 @@ export interface ComponentOptionsBase<
* @internal
*/
__asyncHydrate?: (
el: Element,
instance: ComponentInternalInstance,
hydrate: () => void,
) => void
Expand Down
19 changes: 19 additions & 0 deletions packages/runtime-core/src/hydrationStrategies.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
export type HydrationStrategy = (el: Element, hydrate: () => void) => () => void

export type HydrationStrategyFactory<Options = any> = (
options?: Options,
) => HydrationStrategy

export const hydrateOnTimeout: HydrationStrategyFactory<number> =
(delay = 100) =>
(el, hydrate) =>
() =>
setTimeout(hydrate, delay)

export const hydrateOnVisible: HydrationStrategyFactory<number> = margin => {
return hydrate => () => hydrate
}

export const hydrateOnMediaQuery: HydrationStrategyFactory<string> = query => {
return hydrate => () => hydrate
}
5 changes: 5 additions & 0 deletions packages/runtime-core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ export { useAttrs, useSlots } from './apiSetupHelpers'
export { useModel } from './helpers/useModel'
export { useTemplateRef } from './helpers/useTemplateRef'
export { useId } from './helpers/useId'
export { hydrateOnTimeout } from './hydrationStrategies'

// <script setup> API ----------------------------------------------------------

Expand Down Expand Up @@ -327,6 +328,10 @@ export type {
AsyncComponentOptions,
AsyncComponentLoader,
} from './apiAsyncComponent'
export type {
HydrationStrategy,
HydrationStrategyFactory,
} from './hydrationStrategies'
export type { HMRRuntime } from './hmr'

// Internal API ----------------------------------------------------------------
Expand Down
1 change: 1 addition & 0 deletions packages/runtime-core/src/renderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1327,6 +1327,7 @@ function baseCreateRenderer(

if (isAsyncWrapperVNode) {
;(type as ComponentOptions).__asyncHydrate!(
el as Element,
instance,
hydrateSubTree,
)
Expand Down