signal vs createStore vs createMutable performance for large objects

Goals: 1. A direct mutable vanilla-javascript-like interface to update complex objects 2. Performance for large objects OPTION A: undefined -> set hack Mutate object anyway, set(undefined) -> set(same_mutated_object) wrapped in batch so reactivity only kick off once? Pros: No overhead since same object? Cons: Hack!
const [signal, setSignal] = createSignal({ counts: [1, 1, 1] });

batch(() => {
const temp = signal();
temp.counts.push(1);
temp.counts[0] = temp.counts[0] + 1;
setSignal(undefined);
setSignal(temp);
});
const [signal, setSignal] = createSignal({ counts: [1, 1, 1] });

batch(() => {
const temp = signal();
temp.counts.push(1);
temp.counts[0] = temp.counts[0] + 1;
setSignal(undefined);
setSignal(temp);
});
OPTION B: always equals: false Mutate object anyway, force reactivity trigger with { equals: false } Pros: No overhead since same object? Cons: equals false is dangerous and can easily cause infinite loop
const [signal, setSignal] = createSignal({ counts: [1, 1, 1] }, { equals: false });

batch(() => {
const temp = signal();
temp.counts.push(1);
temp.counts[0] = temp.counts[0] + 1;
setSignal(temp);
});
const [signal, setSignal] = createSignal({ counts: [1, 1, 1] }, { equals: false });

batch(() => {
const temp = signal();
temp.counts.push(1);
temp.counts[0] = temp.counts[0] + 1;
setSignal(temp);
});
OPTION C: createStore with produce Pros: Most recommended Cons: Overhead with createStore? setStore with produce is a bit clunky
const [store, setStore] = createStore({counts: [1, 1, 1]});
setStore(
produce((store) => {
store.counts.push(1);
store.counts[0] = store.counts[0] + 1;
}),
);
const [store, setStore] = createStore({counts: [1, 1, 1]});
setStore(
produce((store) => {
store.counts.push(1);
store.counts[0] = store.counts[0] + 1;
}),
);
OPTION D: createMutable Pros: Most direct, least code, feels like Vue, Svelte, Vanilla Javascript Cons: Overhead with createMutable? Not really recommended, may be deprecated in 2.0. Some bugs and hacks in implementation.
const [store, setStore] = createStore({counts: [1, 1, 1]});
mutableStore.counts.push(1);
mutableStore.counts[0] = mutableStore.counts[0] + 1;
const [store, setStore] = createStore({counts: [1, 1, 1]});
mutableStore.counts.push(1);
mutableStore.counts[0] = mutableStore.counts[0] + 1;
- All code in playground: https://playground.solidjs.com/anonymous/d694e908-c193-494b-ab08-c3e5676269d7 Questions: - I know Option A and B are crazy, but is there anything actually wrong? What cases would those hacks break? Did I miss any gotchas? - Which is best for perf? Would A and B be best since same object is used?
Solid Playground
Quickly discover what the solid compiler will generate from your JSX template
1 Reply
lominming
lominming10mo ago
Please help to elaborate more? I'm leveraging solid's underlying primitives to provide a framework to create components, etc. and I am trying to figure out (1) the DX for the developer, and (2) whether I should hold their reactive bits in signals or stores.