Skip to content

Commit b1b4b37

Browse files
committed
perf(reactivity): use fast path for notify a single effect
1 parent 532ed51 commit b1b4b37

File tree

2 files changed

+40
-43
lines changed

2 files changed

+40
-43
lines changed

packages/reactivity/src/computed.ts

+13-3
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import {
1717
checkDirty,
1818
endTracking,
1919
link,
20-
processComputedUpdate,
20+
shallowPropagate,
2121
startTracking,
2222
} from './system'
2323
import { warn } from './warning'
@@ -138,8 +138,18 @@ export class ComputedRefImpl<T = any> implements Dependency, Subscriber {
138138

139139
get value(): T {
140140
const flags = this.flags
141-
if (flags & (SubscriberFlags.Dirty | SubscriberFlags.Pending)) {
142-
processComputedUpdate(this, flags)
141+
if (
142+
flags & SubscriberFlags.Dirty ||
143+
(flags & SubscriberFlags.Pending && checkDirty(this.deps!))
144+
) {
145+
if (this.update()) {
146+
const subs = this.subs
147+
if (subs !== undefined) {
148+
shallowPropagate(subs)
149+
}
150+
}
151+
} else if (flags & SubscriberFlags.Pending) {
152+
this.flags = flags & ~SubscriberFlags.Pending
143153
}
144154
if (activeSub !== undefined) {
145155
if (__DEV__) {

packages/reactivity/src/system.ts

+27-40
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ export function startBatch(): void {
4747
}
4848

4949
export function endBatch(): void {
50-
if (!--batchDepth) {
50+
if (!--batchDepth && notifyBufferLength) {
5151
processEffectNotifications()
5252
}
5353
}
@@ -62,39 +62,38 @@ export function link(dep: Dependency, sub: Subscriber): void {
6262
sub.depsTail = nextDep
6363
return
6464
}
65-
const depLastSub = dep.subsTail
65+
const prevSub = dep.subsTail
6666
if (
67-
depLastSub !== undefined &&
68-
depLastSub.sub === sub &&
69-
isValidLink(depLastSub, sub)
67+
prevSub !== undefined &&
68+
prevSub.sub === sub &&
69+
isValidLink(prevSub, sub)
7070
) {
7171
return
7272
}
73-
const newLink: Link = {
74-
dep,
75-
sub,
76-
prevDep,
77-
nextDep,
78-
prevSub: undefined,
79-
nextSub: undefined,
73+
const newLink =
74+
(sub.depsTail =
75+
dep.subsTail =
76+
{
77+
dep,
78+
sub,
79+
prevDep,
80+
nextDep,
81+
prevSub,
82+
nextSub: undefined,
83+
})
84+
if (nextDep !== undefined) {
85+
nextDep.prevDep = newLink
8086
}
8187
if (prevDep === undefined) {
8288
sub.deps = newLink
8389
} else {
8490
prevDep.nextDep = newLink
8591
}
86-
if (dep.subs === undefined) {
92+
if (prevSub === undefined) {
8793
dep.subs = newLink
8894
} else {
89-
const oldTail = dep.subsTail!
90-
newLink.prevSub = oldTail
91-
oldTail.nextSub = newLink
92-
}
93-
if (nextDep !== undefined) {
94-
nextDep.prevDep = newLink
95+
prevSub.nextSub = newLink
9596
}
96-
sub.depsTail = newLink
97-
dep.subsTail = newLink
9897
}
9998

10099
export function unlink(
@@ -180,7 +179,11 @@ export function propagate(current: Link): void {
180179

181180
if (shouldNotify) {
182181
if ('notify' in sub) {
183-
notifyBuffer[notifyBufferLength++] = sub
182+
if (!batchDepth && !notifyBufferLength && next === undefined) {
183+
sub.notify()
184+
} else {
185+
notifyBuffer[notifyBufferLength++] = sub
186+
}
184187
} else {
185188
const subSubs = (sub as Dependency).subs
186189
if (subSubs !== undefined) {
@@ -225,7 +228,7 @@ export function propagate(current: Link): void {
225228
break
226229
} while (true)
227230

228-
if (!batchDepth) {
231+
if (!batchDepth && notifyBufferLength) {
229232
processEffectNotifications()
230233
}
231234
}
@@ -251,22 +254,6 @@ export function endTracking(sub: Subscriber): void {
251254
sub.flags &= ~SubscriberFlags.Tracking
252255
}
253256

254-
export function processComputedUpdate(
255-
computed: Computed,
256-
flags: SubscriberFlags,
257-
): void {
258-
if (flags & SubscriberFlags.Dirty || checkDirty(computed.deps!)) {
259-
if (computed.update()) {
260-
const subs = computed.subs
261-
if (subs !== undefined) {
262-
shallowPropagate(subs)
263-
}
264-
}
265-
} else {
266-
computed.flags = flags & ~SubscriberFlags.Pending
267-
}
268-
}
269-
270257
export function processEffectNotifications(): void {
271258
while (notifyIndex < notifyBufferLength) {
272259
const effect = notifyBuffer[notifyIndex]!
@@ -348,7 +335,7 @@ export function checkDirty(current: Link): boolean {
348335
} while (true)
349336
}
350337

351-
function shallowPropagate(link: Link): void {
338+
export function shallowPropagate(link: Link): void {
352339
do {
353340
const sub = link.sub
354341
const subFlags = sub.flags

0 commit comments

Comments
 (0)