使用可写存储处理大型嵌套对象,性能问题



我有一个可写的存储

export default writable({})

我的服务器不断地向这个商店推送更新,这些处理程序在js文件中

const handlers = {
newUser: async (user) => {
userStore.update(user => {
userStore[user.id] = user;
return userStore;
});
},
statusChange: ...
more...
};

用户对象具有多个嵌套对象和数组。我的用户页面有一个#each循环,对于每个用户,它将用户传递给<User />组件。然后,用户组件将其他嵌套对象传递给其他组件,等等。我遇到的问题是,当我更改一个深度嵌套的值时,数百个用户对象和它们所使用的组件会重新运行它们的反应语句。由于这些值大多没有更改,所以它们中的大多数都不会重新发送,但我有大量的代码需要在更改时运行,即使组件实例与未更改的用户相关,这些代码也会重新运行。我尝试过使用嵌套存储,但我的处理程序需要获得(userStore(每一次更新,以此类推,直到我到达实际要更新的存储。另一个问题是:当更改发生在顶层时,即向userStore添加一个新的key: {user},它并没有解决链下更新的问题。

那么,有没有一种正确的方法来进行这种状态管理,而不会在没有变化的地方引起更新?

谢谢。

我能想到的一件事是使用<svelte:options immutable />derived存储。

通过使组件不可变,您可以获得更优化和有限的更新,派生存储引入了自己的更改跟踪,因此,如果您提取对象的属性,对该对象的任何其他更改都不会触发该存储的订阅者。

例如,假设user存储具有name属性,则可以将其解耦为如下组件:

<svelte:options immutable />
<script>
import { derived } from 'svelte/store';

export let user;

const name = derived(user, $user => $user.name);
$: $name, console.log('Name changed.');
</script>
<div>
Name: {$name}
</div>

同样,您可以将{#each}从其他更改中提取出来,而不是直接应用于任何嵌套属性。

更复杂的REPL示例(尝试删除immutable和/或派生存储。(

最新更新