将新项目添加到大型阵列时重新选择的问题

时间:2018-10-30 10:32:28

标签: reactjs redux reselect

我正在使用Reselect为React + Redux创建各种选择器。当我有超过100万个项目时,我会遇到性能问题,选择器的计算可能会花费300毫秒至500毫秒,因为它必须使用昂贵的检查功能对所有项目进行过滤和排序。

我是normalizing的州,在Redux中,我将项目存储在byIds中,并将id存储在allIds中。一切都很好。但是,当我添加新项时,byIdsallIds将被更新,这意味着选择器将不得不再次重新计算所有1M项,而不仅仅是计算新项。

是否有一些聪明的方法可以解决此问题,或者我缺少什么。以前我没有使用任何选择器。这意味着我在将所有新项目添加到商店之前对其进行了过滤,但这带来了我的数据不纯净的副作用。

我考虑过的一些方法是重新构造数据或为数据创建某种层次,以便更好地记住部分数据。

这是我的选择器的结构:

  1. getVisiblePostsIds-获取postsIds,其中包含所有项目的ID并对其进行过滤。例如。阻止或错误类型的项目应被过滤掉。
  2. getSortedPostsIds-获取getVisiblePostsIds并按条件对项目进行排序
  3. getFilteredPostsIds-获取getSortedPostsIds并在项目过多的情况下切片item数组。

如果可能的话,这里是粗糙的源代码。

const getVisiblePostsIds = createSelector(
    [
        getFeedsByIds,
        getPostsIds,
        getPostsByIds,
        getFeedType,
        getStartDate,
        getModerationDict,
    ],
    (
        feedsByIds,
        postsIds,
        postsByIds,
        feedType,
        startTime,
        moderationDict,
    ) => {
        return postsIds.filter(
            postId =>
                postsByIds[postId].created >= startTime
                && feedsByIds[postsByIds[postId].feedId].IgnoreStartDate === false
                && moderationDict[postsByIds[postId].mediaId] === undefined
                && moderationDict[postsByIds[postId].userId] === undefined
                && (feedType === FEED_TYPE.SHOW_BOTH
                    || (feedType === FEED_TYPE.SHOW_MEDIA_FEED_ONLY && postsByIds[postId].type > 1)
                    || (feedType === FEED_TYPE.SHOW_TEXT_FEED_ONLY && postsByIds[postId].type === POST_TYPE.TEXT)),
        )
    },
)

const getSortedPostsIds = createSelector(
    [
        getSlideArrangement,
        getVisiblePostsIds,
        getPostsByIds,
    ],
    (
        slideArrangement,
        postsIds,
        postsByIds,
        // .slice() is supposed to be faster than [...postIds] to clone the array without mutation
    ) => postsIds.slice().sort(comparePosts(postsByIds, slideArrangement)),
)

export const getFilteredPostsIds = createSelector(
    [
        getSortedPostsIds,
        getHasLoopLimit,
        getLoopLimit,
        getSlideArrangement,
    ],
    (
        postsIds,
        hasLoopLimit,
        loopLimit,
        slideArrangement,
    ) => {
        ...array slice
    },
)

谢谢。

0 个答案:

没有答案