]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
wip: optimize vapor currentInstance setting
authorEvan You <evan@vuejs.org>
Sun, 8 Dec 2024 14:32:18 +0000 (22:32 +0800)
committerEvan You <evan@vuejs.org>
Sun, 8 Dec 2024 14:47:05 +0000 (22:47 +0800)
packages/runtime-core/src/componentCurrentInstance.ts
packages/runtime-core/src/index.ts
packages/runtime-vapor/src/block.ts
packages/runtime-vapor/src/component.ts
packages/runtime-vapor/src/hmr.ts
packages/runtime-vapor/src/renderEffect.ts

index b2170a164c5d69030a20fb25f9d772e9670f1ec1..e0322e0c90dc48435abc6f1c7ccc6c9d74b7047e 100644 (file)
@@ -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()
+  }
+}
index 8aabcd3acd0f65c576cc3814962e676d3fa343d8..00bc68573d79fda611aef808d7a4170572b93936 100644 (file)
@@ -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'
index 582ca187b107950c2347a732aed9048980c882d9..a4212714c69abe192d95d1d66553116c3f189269 100644 (file)
@@ -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
     }
index 74e1f812773dcf20607ba8ee4e15e46c89b83292..26dffd336b6b1cb9c2b68c1b2b96f8370e71ff75 100644 (file)
@@ -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(() => {
index 1cdfda3fc4223888cc5d319c651c56573b004092..5e9616b39ca9d4b4bd91e66a97574a5dc4d50f56 100644 (file)
@@ -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)
 }
 
index 17128d23376499fbde8a25c518d4b4d7e17078cd..fdd58b38b93a6912f064200381919c451806ec94 100644 (file)
@@ -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