When do Svelte derived stores cause a re-render?

Viewed 62

If dealing with a store shaped like this:

{
  "count": 0,
  "items": []
}

And having two derived stores ($countStore and $itemsStore) that return the respective fields, updating items on the main store does not cause a re-render on components that depend on just countStore, but updating count does cause a render on components that depend on just itemsStore, why exactly is that?

Here's a REPL showing this behavior.

I would assume this happens for all non-primitive fields, but selectors in Redux for example don't have this behavior, so how does Svelte diff derived stores? Does it simply ignore non-primitive fields causing renders for every update? If so, is there a way to save on renders when dealing with objects?

1 Answers

Svelte uses a function called safe_not_equal to check whether a value potentially changed; this is not unique to derived stores. derived uses a readable store internally and the check happens on setting its value.

export function safe_not_equal(a, b) {
    return a != a ? b == b : a !== b || ((a && typeof a === 'object') || typeof a === 'function');
}

So yes, non-primitive values are not considered the same, because they could potentially have changed internally. Svelte already optimizes updates to only cause minimal updates to the DOM, so I would not worry about this unless it really becomes an issue. For arrays you should use keyed {#each}-blocks to keep the DOM elements synchronized with their respective items.

Related