From: Evan You Date: Sun, 8 Dec 2024 14:32:18 +0000 (+0800) Subject: wip: optimize vapor currentInstance setting X-Git-Tag: v3.6.0-alpha.1~16^2~198 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=83be45ea88276c0676bb08241484948fda2970dc;p=thirdparty%2Fvuejs%2Fcore.git wip: optimize vapor currentInstance setting --- diff --git a/packages/runtime-core/src/componentCurrentInstance.ts b/packages/runtime-core/src/componentCurrentInstance.ts index b2170a164c..e0322e0c90 100644 --- a/packages/runtime-core/src/componentCurrentInstance.ts +++ b/packages/runtime-core/src/componentCurrentInstance.ts @@ -74,9 +74,6 @@ if (__SSR__) { } } -/** - * @internal - */ export const setCurrentInstance = (instance: GenericComponentInstance) => { const prev = currentInstance internalSetCurrentInstance(instance) @@ -91,3 +88,20 @@ export const unsetCurrentInstance = (): void => { currentInstance && currentInstance.scope.off() internalSetCurrentInstance(null) } + +/** + * Exposed for vapor only. Vapor never runs during SSR so we don't want to pay + * for the extra overhead + * @internal + */ +export const simpleSetCurrentInstance = ( + i: GenericComponentInstance | null, + unset?: GenericComponentInstance, +): void => { + currentInstance = i + if (unset) { + unset.scope.off() + } else if (i) { + i.scope.on() + } +} diff --git a/packages/runtime-core/src/index.ts b/packages/runtime-core/src/index.ts index 8aabcd3acd..00bc68573d 100644 --- a/packages/runtime-core/src/index.ts +++ b/packages/runtime-core/src/index.ts @@ -507,5 +507,8 @@ export { type AppMountFn, type AppUnmountFn, } from './apiCreateApp' -export { currentInstance, setCurrentInstance } from './componentCurrentInstance' +export { + currentInstance, + simpleSetCurrentInstance, +} from './componentCurrentInstance' export { registerHMR, unregisterHMR } from './hmr' diff --git a/packages/runtime-vapor/src/block.ts b/packages/runtime-vapor/src/block.ts index 582ca187b1..a4212714c6 100644 --- a/packages/runtime-vapor/src/block.ts +++ b/packages/runtime-vapor/src/block.ts @@ -38,7 +38,7 @@ export class DynamicFragment extends Fragment { // teardown previous branch if (this.scope) { - this.scope.off() + this.scope.stop() parent && remove(this.nodes, parent) // TODO lifecycle unmount } diff --git a/packages/runtime-vapor/src/component.ts b/packages/runtime-vapor/src/component.ts index 74e1f81277..26dffd336b 100644 --- a/packages/runtime-vapor/src/component.ts +++ b/packages/runtime-vapor/src/component.ts @@ -15,7 +15,8 @@ import { popWarningContext, pushWarningContext, registerHMR, - setCurrentInstance, + simpleSetCurrentInstance, + unregisterHMR, warn, } from '@vue/runtime-dom' import { type Block, isBlock } from './block' @@ -115,7 +116,8 @@ export function createComponent( } const instance = new VaporComponentInstance(component, rawProps, rawSlots) - const resetCurrentInstance = setCurrentInstance(instance) + const prev = currentInstance + simpleSetCurrentInstance(instance) pauseTracking() if (__DEV__) { @@ -146,9 +148,11 @@ export function createComponent( devRender(instance) // HMR - registerHMR(instance) - instance.hmrRerender = hmrRerender.bind(null, instance) - instance.hmrReload = hmrReload.bind(null, instance) + if (component.__hmrId) { + registerHMR(instance) + instance.hmrRerender = hmrRerender.bind(null, instance) + instance.hmrReload = hmrReload.bind(null, instance) + } } } else { // in prod result can only be block @@ -173,7 +177,7 @@ export function createComponent( popWarningContext() } resetTracking() - resetCurrentInstance() + simpleSetCurrentInstance(prev, instance) return instance } @@ -414,7 +418,11 @@ export function unmountComponent( parent: ParentNode, ): void { if (instance.isMounted && !instance.isUnmounted) { + if (__DEV__ && instance.type.__hmrId) { + unregisterHMR(instance) + } if (instance.bum) invokeArrayFns(instance.bum) + instance.scope.stop() // TODO invoke unmount recursively for children remove(instance.block, parent) // queuePostFlushCb(() => { diff --git a/packages/runtime-vapor/src/hmr.ts b/packages/runtime-vapor/src/hmr.ts index 1cdfda3fc4..5e9616b39c 100644 --- a/packages/runtime-vapor/src/hmr.ts +++ b/packages/runtime-vapor/src/hmr.ts @@ -1,7 +1,8 @@ import { + currentInstance, popWarningContext, pushWarningContext, - setCurrentInstance, + simpleSetCurrentInstance, } from '@vue/runtime-core' import { normalizeBlock } from './block' import { type VaporComponentInstance, devRender } from './component' @@ -12,11 +13,12 @@ export function hmrRerender(instance: VaporComponentInstance): void { const parent = normalized[0].parentNode! const anchor = normalized[normalized.length - 1].nextSibling remove(instance.block, parent) - const reset = setCurrentInstance(instance) + const prev = currentInstance + simpleSetCurrentInstance(instance) pushWarningContext(instance) devRender(instance) - reset() popWarningContext() + simpleSetCurrentInstance(prev, instance) insert(instance.block, parent, anchor) } diff --git a/packages/runtime-vapor/src/renderEffect.ts b/packages/runtime-vapor/src/renderEffect.ts index 17128d2337..fdd58b38b9 100644 --- a/packages/runtime-vapor/src/renderEffect.ts +++ b/packages/runtime-vapor/src/renderEffect.ts @@ -4,7 +4,7 @@ import { currentInstance, queueJob, queuePostFlushCb, - setCurrentInstance, + simpleSetCurrentInstance, warn, } from '@vue/runtime-dom' import { type VaporComponentInstance, isVaporComponent } from './component' @@ -16,28 +16,30 @@ export function renderEffect(fn: () => void, noLifecycle = false): void { warn('renderEffect called without active vapor instance.') } - const effect = new ReactiveEffect( - noLifecycle - ? fn - : () => { - const reset = setCurrentInstance(instance) - const { isMounted, isUpdating, bu, u } = instance - // before update - if (isMounted && !isUpdating && (bu || u)) { - instance.isUpdating = true - bu && invokeArrayFns(bu) - fn() - queuePostFlushCb(() => { - instance.isUpdating = false - u && invokeArrayFns(u) - }) - } else { - fn() - } - reset() - }, - ) + const renderEffectFn = noLifecycle + ? fn + : () => { + const prev = currentInstance + simpleSetCurrentInstance(instance) + if ( + instance.isMounted && + !instance.isUpdating && + (instance.bu || instance.u) + ) { + instance.isUpdating = true + instance.bu && invokeArrayFns(instance.bu) + fn() + queuePostFlushCb(() => { + instance.isUpdating = false + instance.u && invokeArrayFns(instance.u) + }) + } else { + fn() + } + simpleSetCurrentInstance(prev, instance) + } + const effect = new ReactiveEffect(renderEffectFn) const job: SchedulerJob = effect.runIfDirty.bind(effect) job.i = instance job.id = instance.uid