Skip to content

Commit

Permalink
perf: reduce call stacks for cleaning up the subscription chain
Browse files Browse the repository at this point in the history
  • Loading branch information
johnsoncodehk committed Oct 12, 2024
1 parent 63f3de2 commit 8f13824
Show file tree
Hide file tree
Showing 6 changed files with 25 additions and 26 deletions.
7 changes: 1 addition & 6 deletions lib/computed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,6 @@ export class Computed<T = any> implements Dependency, Subscriber {
public getter: (cachedValue?: T) => T
) { }

notifyLostSubs() {
Subscriber.clearTrack(this);
this.versionOrDirtyLevel = DirtyLevels.Dirty;
}

get(): T {
Dependency.linkSubOnly(this);
const dirtyLevel = this.versionOrDirtyLevel;
Expand All @@ -34,7 +29,7 @@ export class Computed<T = any> implements Dependency, Subscriber {
if (this.versionOrDirtyLevel === DirtyLevels.Dirty) {
return this.update();
}
} else if (dirtyLevel === DirtyLevels.Dirty) {
} else if (dirtyLevel >= DirtyLevels.Dirty) {
return this.update();
}
return this.cachedValue!;
Expand Down
4 changes: 0 additions & 4 deletions lib/effect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,6 @@ export class Effect implements IEffect, Dependency, Subscriber {
Dependency.link(this);
}

notifyLostSubs() {
Subscriber.clearTrack(this);
}

notify() {
const dirtyLevel = this.versionOrDirtyLevel;
if (dirtyLevel === DirtyLevels.SideEffectsOnly) {
Expand Down
9 changes: 7 additions & 2 deletions lib/effectScope.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { DirtyLevels, IEffect, Subscriber } from './system.js';
import { DirtyLevels, IEffect, Link, Subscriber } from './system.js';

export function effectScope() {
return new EffectScope();
Expand Down Expand Up @@ -27,6 +27,11 @@ export class EffectScope implements IEffect, Subscriber {
}

stop() {
Subscriber.clearTrack(this);
if (this.deps !== undefined) {
Link.releaseDeps(this.deps);
Link.release(this.deps);
this.deps = undefined;
}
this.versionOrDirtyLevel = DirtyLevels.None;
}
}
21 changes: 9 additions & 12 deletions lib/system.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ export interface Dependency {
subs: Link | undefined;
subsTail: Link | undefined;
subVersion: number;
notifyLostSubs?(): void;
update?(): void;
}

Expand Down Expand Up @@ -37,6 +36,7 @@ export const enum DirtyLevels {
SideEffectsOnly,
MaybeDirty,
Dirty,
Released,
}

export namespace System {
Expand All @@ -45,7 +45,7 @@ export namespace System {
export let activeSubsDepth = 0;
export let activeSubIsScopeOrNothing = true;
export let batchDepth = 0;
export let lastSubVersion = DirtyLevels.Dirty + 1;
export let lastSubVersion = DirtyLevels.Released + 1;
export let queuedEffects: IEffect | undefined = undefined;
export let queuedEffectsTail: IEffect | undefined = undefined;

Expand Down Expand Up @@ -135,8 +135,13 @@ export namespace Link {
link.queuedPropagateOrNextReleased = pool;
pool = link;

if (dep.subs === undefined && 'notifyLostSubs' in dep) {
dep.notifyLostSubs!();
if (dep.subs === undefined && 'deps' in dep) {
if (dep.deps !== undefined) {
Link.releaseDeps(dep.deps);
Link.release(dep.deps);
dep.deps = undefined;
}
dep.versionOrDirtyLevel = DirtyLevels.Released;
}
}
}
Expand Down Expand Up @@ -479,15 +484,7 @@ export namespace Subscriber {
} else {
system.activeSubIsScopeOrNothing = true;
}
postTrack(sub);
}

export function clearTrack(sub: Subscriber) {
sub.depsTail = undefined;
postTrack(sub);
}

function postTrack(sub: Subscriber) {
if (sub.depsTail !== undefined) {
Link.releaseDeps(sub.depsTail);
} else if (sub.deps !== undefined) {
Expand Down
2 changes: 1 addition & 1 deletion tests/effect.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ test('should clear subscriptions when untracked by all subscribers', () => {


expect(!!b.subs).toBe(true);
Subscriber.clearTrack(effect1);
Subscriber.endTrack(effect1, Subscriber.startTrack(effect1));
expect(!!b.subs).toBe(false);
});

Expand Down
8 changes: 7 additions & 1 deletion unstable/vue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
DirtyLevels,
Effect,
EffectScope,
Link,
Signal,
Subscriber,
System,
Expand Down Expand Up @@ -97,7 +98,12 @@ export class ReactiveEffect extends Effect {
}

stop() {
Subscriber.clearTrack(this);
if (this.deps !== undefined) {
Link.releaseDeps(this.deps);
Link.release(this.deps);
this.deps = undefined;
}
this.versionOrDirtyLevel = DirtyLevels.None;
}
}

Expand Down

0 comments on commit 8f13824

Please sign in to comment.