Skip to content

Commit 46c9dbe

Browse files
committed
Breadth first calling of subscribers in store dependency tree.
Optimize performance by using subscriber_queue.
1 parent bbeafba commit 46c9dbe

File tree

1 file changed

+12
-23
lines changed

1 file changed

+12
-23
lines changed

src/runtime/store/index.ts

Lines changed: 12 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ export interface Writable<T> extends Readable<T> {
4444
/** Pair of subscriber and invalidator. */
4545
type SubscribeInvalidateTuple<T> = [Subscriber<T>, Invalidator<T>];
4646

47+
const subscriber_queue = [];
48+
4749
/**
4850
* Creates a `Readable` store that allows reading by subscription.
4951
* @param value initial value
@@ -69,7 +71,15 @@ export function writable<T>(value: T, start: StartStopNotifier<T> = noop): Writa
6971
value = new_value;
7072
if (stop) { // store is ready
7173
subscribers.forEach((s) => s[1]());
72-
subscribers.forEach((s) => s[0](value));
74+
const run_queue = !subscriber_queue.length;
75+
subscribers.forEach(s => subscriber_queue.push(s, value));
76+
if (run_queue) {
77+
let s;
78+
while (s = subscriber_queue.shift()) {
79+
const val = subscriber_queue.shift();
80+
s[0](val);
81+
}
82+
}
7383
}
7484
}
7585
}
@@ -128,10 +138,6 @@ export function derived<T, S extends Stores>(
128138

129139
const auto = fn.length < 2;
130140

131-
const subscribers: Array<Subscriber<T>> = [];
132-
const invalidators: Array<Invalidator<T>> = [];
133-
let value: T = initial_value;
134-
135141
const store = readable(initial_value, (set) => {
136142
let inited = false;
137143
const values: StoresValues<S> = [] as StoresValues<S>;
@@ -147,11 +153,6 @@ export function derived<T, S extends Stores>(
147153
const result = fn(single ? values[0] : values, set);
148154
if (auto) {
149155
set(result as T);
150-
const dirty = safe_not_equal(value, result);
151-
value = result as T;
152-
if (!dirty) {
153-
subscribers.forEach(s => s(value));
154-
}
155156
} else {
156157
cleanup = is_function(result) ? result as Unsubscriber : noop;
157158
}
@@ -166,7 +167,6 @@ export function derived<T, S extends Stores>(
166167
}
167168
},
168169
() => {
169-
run_all(invalidators);
170170
pending |= (1 << i);
171171
}),
172172
);
@@ -182,18 +182,7 @@ export function derived<T, S extends Stores>(
182182

183183
return {
184184
subscribe(run: Subscriber<T>, invalidate: Invalidator<T> = noop): Unsubscriber {
185-
subscribers.push(run);
186-
invalidators.push(invalidate);
187-
188-
const unsubscribe = store.subscribe(run, invalidate);
189-
190-
return () => {
191-
const index = invalidators.indexOf(invalidate);
192-
if (index !== -1) {
193-
invalidators.splice(index, 1);
194-
}
195-
unsubscribe();
196-
};
185+
return store.subscribe(run, invalidate);
197186
}
198187
};
199188
}

0 commit comments

Comments
 (0)