Description
Using {#each...} with list/array from store updates all items from list while this can be avoided with immutable writable stores. I have expected that using <svelte:options immutable={true} />
would allow that (as per documentation "you never use mutable data, so the compiler can do simple referential equality checks to determine if values have changed" here https://svelte.dev/docs) but that's not the case.
Here I have created sample https://github.com/daliusd/svelte_immutable_store app to demonstrate the problem. Run it, open dev tools and modify text or or add new item. You will see that afterUpdate
(https://github.com/daliusd/svelte_immutable_store/blob/ebc1bd4bd00a3d4a7687f5b13d484fd0135e6a1d/src/Item.svelte#L8) is called for each item even if we are updating only single item.
Here you can see https://github.com/daliusd/svelte_immutable_store/blob/master/src/store.js that I do not mutate my data thus references will not change.
Describe the solution you'd like
I think writable store should respect <svelte:options immutable={true} />
. I think this might be not enough however as internal svelte code might not handle lists/arrays properly. I have not looked that deep into Svelte's code.
As well I think that by default svelte should create mutable stores (as it is now).
Describe alternatives you've considered
In some old version svelte supported immutable stores (see #1146). But I assume that was removed somewhere in progress. I think respecting global setting is better option as that would make app consistent and developer shouldn't think if this store is mutable or immutable.
How important is this feature to you?
Modern browsers seems to handle updates that do not change anything quite well. E.g. if you change div's position to the same value there will be no physical re-render. That makes this problem quite low priority IMHO.
From other side in one app of mine I do canvas re-render after update. That means I can not do re-render after each update because afterUpdate (or whatever is reactive) is called for all items even if I update only one item. I found workaround for this problem but it is second workaround I have to do in Svelte (bug is reported for first one already by other people).
Additional context
As well I see #2171 which explicitly states that stores are always mutable.
Lastly, in svelte's source code I see those functions. That's just my curiosity:
export function safe_not_equal(a, b) {
return a != a ? b == b : a !== b || ((a && typeof a === 'object') || typeof a === 'function');
}
export function not_equal(a, b) {
return a != a ? b == b : a !== b;
}
Now I wonder why we have this part a != a ? b == b : a !== b
. a != a
is true only for NaN, that means this line overrides/inverts NaN behavior. Is that intentional?