Я использую Повторный выбор для создания различных селекторов для React + Redux. У меня возникают проблемы с производительностью, когда у меня более 1 млн элементов, вычисление селектора может занять от 300 мс до 500 мс, поскольку оно должно фильтровать и сортировать все элементы с дорогими проверками.
Я нормализую состояние в Redux, где у меня есть элементы, хранящиеся в byIds
, и идентификаторы, хранящиеся в allIds
. Это все хорошо. Но когда я добавляю новый элемент, byIds
и allIds
будут обновлены, а это означает, что селектору придется заново вычислять все элементы 1M, а не просто вычислять новый элемент.
Есть какой-нибудь умный способ решить это, или я что-то упускаю. Ранее я не использовал селекторы. Это означало, что я отфильтровал все новые элементы до того, как они были добавлены в хранилище, но это привело к тому, что мои данные не были чистыми.
Некоторые методы, о которых я думал, - это реструктуризация моих данных или создание каких-то слоев для данных, чтобы я мог лучше запомнить их часть.
Вот структура моих селекторов:
- getVisiblePostsIds - получает
postsIds
, который имеет идентификатор всех элементов и фильтрует их. Например. элемент, который заблокирован или имеет неправильный тип, должен быть отфильтрован.
- getSortedPostsIds - получает
getVisiblePostsIds
и сортирует элементы по условию
- getFilteredPostsIds - получает
getSortedPostsIds
и нарезает массив элементов, если их слишком много.
Вот примерный исходный код, если он может помочь.
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
},
)
Спасибо.