perf(reactivity): optimize effect stack
This commit is contained in:
parent
49a50d3c9c
commit
46c5393224
@ -1,4 +1,4 @@
|
|||||||
import { effect, ReactiveEffect, effectStack } from './effect'
|
import { effect, ReactiveEffect, activeEffect } from './effect'
|
||||||
import { Ref, UnwrapRef } from './ref'
|
import { Ref, UnwrapRef } from './ref'
|
||||||
import { isFunction, NOOP } from '@vue/shared'
|
import { isFunction, NOOP } from '@vue/shared'
|
||||||
|
|
||||||
@ -73,15 +73,14 @@ export function computed<T>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
function trackChildRun(childRunner: ReactiveEffect) {
|
function trackChildRun(childRunner: ReactiveEffect) {
|
||||||
if (effectStack.length === 0) {
|
if (activeEffect === undefined) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const parentRunner = effectStack[effectStack.length - 1]
|
|
||||||
for (let i = 0; i < childRunner.deps.length; i++) {
|
for (let i = 0; i < childRunner.deps.length; i++) {
|
||||||
const dep = childRunner.deps[i]
|
const dep = childRunner.deps[i]
|
||||||
if (!dep.has(parentRunner)) {
|
if (!dep.has(activeEffect)) {
|
||||||
dep.add(parentRunner)
|
dep.add(activeEffect)
|
||||||
parentRunner.deps.push(dep)
|
activeEffect.deps.push(dep)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,7 +40,8 @@ export interface DebuggerEventExtraInfo {
|
|||||||
oldTarget?: Map<any, any> | Set<any>
|
oldTarget?: Map<any, any> | Set<any>
|
||||||
}
|
}
|
||||||
|
|
||||||
export const effectStack: ReactiveEffect[] = []
|
const effectStack: ReactiveEffect[] = []
|
||||||
|
export let activeEffect: ReactiveEffect | undefined
|
||||||
|
|
||||||
export const ITERATE_KEY = Symbol('iterate')
|
export const ITERATE_KEY = Symbol('iterate')
|
||||||
|
|
||||||
@ -95,9 +96,11 @@ function run(effect: ReactiveEffect, fn: Function, args: unknown[]): unknown {
|
|||||||
cleanup(effect)
|
cleanup(effect)
|
||||||
try {
|
try {
|
||||||
effectStack.push(effect)
|
effectStack.push(effect)
|
||||||
|
activeEffect = effect
|
||||||
return fn(...args)
|
return fn(...args)
|
||||||
} finally {
|
} finally {
|
||||||
effectStack.pop()
|
effectStack.pop()
|
||||||
|
activeEffect = effectStack[effectStack.length - 1]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -123,10 +126,9 @@ export function resumeTracking() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function track(target: object, type: TrackOpTypes, key: unknown) {
|
export function track(target: object, type: TrackOpTypes, key: unknown) {
|
||||||
if (!shouldTrack || effectStack.length === 0) {
|
if (!shouldTrack || activeEffect === undefined) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const effect = effectStack[effectStack.length - 1]
|
|
||||||
let depsMap = targetMap.get(target)
|
let depsMap = targetMap.get(target)
|
||||||
if (depsMap === void 0) {
|
if (depsMap === void 0) {
|
||||||
targetMap.set(target, (depsMap = new Map()))
|
targetMap.set(target, (depsMap = new Map()))
|
||||||
@ -135,12 +137,12 @@ export function track(target: object, type: TrackOpTypes, key: unknown) {
|
|||||||
if (dep === void 0) {
|
if (dep === void 0) {
|
||||||
depsMap.set(key, (dep = new Set()))
|
depsMap.set(key, (dep = new Set()))
|
||||||
}
|
}
|
||||||
if (!dep.has(effect)) {
|
if (!dep.has(activeEffect)) {
|
||||||
dep.add(effect)
|
dep.add(activeEffect)
|
||||||
effect.deps.push(dep)
|
activeEffect.deps.push(dep)
|
||||||
if (__DEV__ && effect.options.onTrack) {
|
if (__DEV__ && activeEffect.options.onTrack) {
|
||||||
effect.options.onTrack({
|
activeEffect.options.onTrack({
|
||||||
effect,
|
effect: activeEffect,
|
||||||
target,
|
target,
|
||||||
type,
|
type,
|
||||||
key
|
key
|
||||||
|
Loading…
Reference in New Issue
Block a user