在终极版
我的终极版店看起来是这样的:在终极版
threads: [ {id: 1, board: 1}, ...], posts: [ {id: 1, thread: 1}, ...]
查看板将新增20个线程商店。并且线程的每个页面将向商店添加20个帖子。
除此之外,每秒都会自动发布新帖子和线索。
这使得董事会的代码确实是这样的:
threads.filter(thread => thread.boardId == props.params.boardId)
所以每次访问车上时间将被过滤上百个线程。每个线程将通过每个页面的数千个帖子进行过滤。
这会发生多大的性能问题,我该如何最好地避免它们?
我看着reselect,但似乎它将不得不重新计算每个视图,因为过滤器无论如何改变。
现在,让我们假设您将会忽略reselect,直到您需要为止。当您缩放时,它是一个方便的工具,但可以在需要时稍后展开,而不会有太多麻烦。
一个相当有用的方法(被提取到一个同样有用的库中,名为normalizr)是对象数组集合的规范化。考虑到你在你的问题中描述的状态,你应该肯定检查它背后的逻辑。这样做会为您的商店收藏提供替代结构,该替代结构适用于选择个别元素,同时不会影响的显着过滤的效果。
腾起权,你的状态可能可能最终看起来像:
boards: {
entities: {
board0: { id: "board0", threads: [ thread2, thread4, ...], data: ... },
board1: { id: "board1", threads: [ thread0, thread3, ...], data: ... },
},
ids: [ board0, board1, ... ],
},
threads: {
entities: {
thread0: { id: "thread0", posts: [ post0, post4, ... ], data: ... },
thread1: { id: "thread1", posts: [ post2, post3, ... ], data: ... },
},
ids: [ thread0, thread1, ... ],
},
posts: {
entities: {
post0: { id: "post0", data: ... },
post1: { id: "post1", data: ... },
},
ids: [ post0, post1, ... ],
},
这适用于一堆理由。首先,传入的帖子和线程通过动作添加到状态,这意味着您可以很容易地将它们标准化为,因为它们在中。不要将完整的线程对象直接放入threads
阵列,而是将其添加到threads.entities.<threadId>
并使用它的ID更新boards.<currentBoardId>.threads
阵列。传入的post
对象也是如此。就这样,它正常化了。
现在,当涉及到显示组件时,每个board
都有一个非常轻量级的列表,名为threads
。而不是一个长度为boards * threads
的数组上的过滤器,您可以通过仅在该电路板上可见的线程ID数组映射一个映射,并且具有固有快速的字典查找。
线程可见板:
const boardThreads = boards.entities[props.params.boardId].threads
.map(threadId => threads.entities[threadId]
帖子所选主题:
const threadPosts = threads.entities[selectedThreadId].posts
.map(postId => posts.entities[postId])
为每个集合额外ids
场是没有必要的,但我觉得它有用。例如,列出所有板:
const allBoards = boards.ids.map(id => boards.entities[id])
这可能,但是,仅仅是使用Object.keys
功能,而不是完成。直到开发。
应该说这是一个简单的数组过滤器,可能需要考虑在状态中添加新对象。然而,我提供的三个例子包括没有数组过滤无论如何,存储中使用的所有数组只是ID数组(通常是非常简单的字符串)。另外,这确保了与实体相关联的数据仅在一个地方(collection.entities
)中被存储在中,即使在其增长时也保持状态为精益和一致。
如果你没有真正遇到性能损失,你不应该担心它。 重新选择可能是您的情况的一个很好的选择,因为它的缓存能力。 – Scarysize