Skip to content

Commit

Permalink
perf(reactivity): better computed tracking (#710)
Browse files Browse the repository at this point in the history
  • Loading branch information
jods4 authored Feb 9, 2020
1 parent fc7bcca commit 8874b21
Showing 1 changed file with 10 additions and 20 deletions.
30 changes: 10 additions & 20 deletions packages/reactivity/src/computed.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { effect, ReactiveEffect, activeEffect } from './effect'
import { effect, ReactiveEffect, trigger, track } from './effect'
import { TriggerOpTypes, TrackOpTypes } from './operations'
import { Ref, UnwrapRef } from './ref'
import { isFunction, NOOP } from '@vue/shared'

Expand Down Expand Up @@ -42,16 +43,20 @@ export function computed<T>(

let dirty = true
let value: T
let computed: ComputedRef<T>

const runner = effect(getter, {
lazy: true,
// mark effect as computed so that it gets priority during trigger
computed: true,
scheduler: () => {
dirty = true
if (!dirty) {
dirty = true
trigger(computed, TriggerOpTypes.SET, 'value')
}
}
})
return {
computed = {
_isRef: true,
// expose effect so computed can be stopped
effect: runner,
Expand All @@ -60,27 +65,12 @@ export function computed<T>(
value = runner()
dirty = false
}
// When computed effects are accessed in a parent effect, the parent
// should track all the dependencies the computed property has tracked.
// This should also apply for chained computed properties.
trackChildRun(runner)
track(computed, TrackOpTypes.GET, 'value')
return value
},
set value(newValue: T) {
setter(newValue)
}
} as any
}

function trackChildRun(childRunner: ReactiveEffect) {
if (activeEffect === undefined) {
return
}
for (let i = 0; i < childRunner.deps.length; i++) {
const dep = childRunner.deps[i]
if (!dep.has(activeEffect)) {
dep.add(activeEffect)
activeEffect.deps.push(dep)
}
}
return computed
}

0 comments on commit 8874b21

Please sign in to comment.