Cache the processing of ChannelMentionSuggestions (#309)
## Issue One of the bottlenecks of livestream page. The component probably needs a re-design: - Don't perpetually mount -- only mount when activated by the user through "@". This would avoid the heavy processing entirely. - Better way of resolving uris (too many arrays, too many loops). - Tom also mentioned that we should not be resolving every commenter as we see encounter them in a livestream. This is currently the case because the component is always mounted. ## Changes Until the re-design occurs, attempt to cache the heavy processing. Also, trimmed down the amount of loops.
This commit is contained in:
parent
47c316e0ad
commit
e35069de1c
2 changed files with 78 additions and 27 deletions
|
@ -3,38 +3,23 @@ import { MAX_LIVESTREAM_COMMENTS } from 'constants/livestream';
|
||||||
import { selectShowMatureContent } from 'redux/selectors/settings';
|
import { selectShowMatureContent } from 'redux/selectors/settings';
|
||||||
import { selectSubscriptionUris } from 'redux/selectors/subscriptions';
|
import { selectSubscriptionUris } from 'redux/selectors/subscriptions';
|
||||||
import { withRouter } from 'react-router';
|
import { withRouter } from 'react-router';
|
||||||
import { makeSelectClaimForUri } from 'redux/selectors/claims';
|
import { selectCanonicalUrlForUri } from 'redux/selectors/claims';
|
||||||
import { doResolveUris } from 'redux/actions/claims';
|
import { doResolveUris } from 'redux/actions/claims';
|
||||||
import { selectTopLevelCommentsForUri } from 'redux/selectors/comments';
|
import { selectChannelMentionData } from 'redux/selectors/livestream';
|
||||||
import ChannelMentionSuggestions from './view';
|
import ChannelMentionSuggestions from './view';
|
||||||
|
|
||||||
const select = (state, props) => {
|
const select = (state, props) => {
|
||||||
const subscriptionUris = selectSubscriptionUris(state);
|
const maxComments = props.isLivestream ? MAX_LIVESTREAM_COMMENTS : -1;
|
||||||
const topLevelComments = selectTopLevelCommentsForUri(
|
const data = selectChannelMentionData(state, props.uri, maxComments);
|
||||||
state,
|
|
||||||
props.uri,
|
|
||||||
props.isLivestream ? MAX_LIVESTREAM_COMMENTS : -1
|
|
||||||
);
|
|
||||||
|
|
||||||
const commentorUris = [];
|
|
||||||
// Avoid repeated commentors
|
|
||||||
topLevelComments.map(({ channel_url }) => !commentorUris.includes(channel_url) && commentorUris.push(channel_url));
|
|
||||||
|
|
||||||
const getUnresolved = (uris) =>
|
|
||||||
uris.map((uri) => !makeSelectClaimForUri(uri)(state) && uri).filter((uri) => uri !== false);
|
|
||||||
const getCanonical = (uris) =>
|
|
||||||
uris
|
|
||||||
.map((uri) => makeSelectClaimForUri(uri)(state) && makeSelectClaimForUri(uri)(state).canonical_url)
|
|
||||||
.filter((uri) => Boolean(uri));
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
commentorUris,
|
commentorUris: data.commentorUris,
|
||||||
subscriptionUris,
|
subscriptionUris: selectSubscriptionUris(state),
|
||||||
unresolvedCommentors: getUnresolved(commentorUris),
|
unresolvedCommentors: data.unresolvedCommentors,
|
||||||
unresolvedSubscriptions: getUnresolved(subscriptionUris),
|
unresolvedSubscriptions: data.unresolvedSubscriptions,
|
||||||
canonicalCreator: getCanonical([props.creatorUri])[0],
|
canonicalCreator: selectCanonicalUrlForUri(state, props.creatorUri),
|
||||||
canonicalCommentors: getCanonical(commentorUris),
|
canonicalCommentors: data.canonicalCommentors,
|
||||||
canonicalSubscriptions: getCanonical(subscriptionUris),
|
canonicalSubscriptions: data.canonicalSubscriptions,
|
||||||
showMature: selectShowMatureContent(state),
|
showMature: selectShowMatureContent(state),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
// @flow
|
// @flow
|
||||||
import { createSelector } from 'reselect';
|
import { createSelector } from 'reselect';
|
||||||
import { createCachedSelector } from 're-reselect';
|
import { createCachedSelector } from 're-reselect';
|
||||||
import { selectMyClaims, selectPendingClaims } from 'redux/selectors/claims';
|
import { selectMyClaims, selectPendingClaims, selectClaimIdsByUri, selectClaimsById } from 'redux/selectors/claims';
|
||||||
|
import { selectTopLevelCommentsForUri } from 'redux/selectors/comments';
|
||||||
|
import { selectSubscriptionUris } from 'redux/selectors/subscriptions';
|
||||||
|
|
||||||
type State = { livestream: any };
|
type State = { livestream: any };
|
||||||
|
|
||||||
|
@ -61,3 +63,67 @@ export const selectIsActiveLivestreamForUri = createCachedSelector(
|
||||||
return activeLivestreamValues.some((v) => v.latestClaimUri === uri);
|
return activeLivestreamValues.some((v) => v.latestClaimUri === uri);
|
||||||
}
|
}
|
||||||
)((state, uri) => String(uri));
|
)((state, uri) => String(uri));
|
||||||
|
|
||||||
|
// ****************************************************************************
|
||||||
|
// Temporary
|
||||||
|
// ****************************************************************************
|
||||||
|
|
||||||
|
// Until ChannelMentions is redesigned, this serves as a cached and leaner
|
||||||
|
// version of the original code.
|
||||||
|
export const selectChannelMentionData = createCachedSelector(
|
||||||
|
selectClaimIdsByUri,
|
||||||
|
selectClaimsById,
|
||||||
|
selectTopLevelCommentsForUri,
|
||||||
|
selectSubscriptionUris,
|
||||||
|
(claimIdsByUri, claimsById, topLevelComments, subscriptionUris) => {
|
||||||
|
const commentorUris = [];
|
||||||
|
const unresolvedCommentors = [];
|
||||||
|
const unresolvedSubscriptions = [];
|
||||||
|
const canonicalCommentors = [];
|
||||||
|
const canonicalSubscriptions = [];
|
||||||
|
|
||||||
|
topLevelComments.forEach((comment) => {
|
||||||
|
const uri = comment.channel_url;
|
||||||
|
|
||||||
|
if (!commentorUris.includes(uri)) {
|
||||||
|
// Update: commentorUris
|
||||||
|
commentorUris.push(uri);
|
||||||
|
|
||||||
|
// Update: unresolvedCommentors
|
||||||
|
const claimId = claimIdsByUri[uri];
|
||||||
|
if (claimId === undefined) {
|
||||||
|
unresolvedCommentors.push(uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update: canonicalCommentors
|
||||||
|
const claim = claimsById[claimId];
|
||||||
|
if (claim && claim.canonical_url) {
|
||||||
|
canonicalCommentors.push(claim.canonical_url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
subscriptionUris.forEach((uri) => {
|
||||||
|
// Update: unresolvedSubscriptions
|
||||||
|
const claimId = claimIdsByUri[uri];
|
||||||
|
if (claimId === undefined) {
|
||||||
|
unresolvedSubscriptions.push(uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update: canonicalSubscriptions
|
||||||
|
const claim = claimsById[claimId];
|
||||||
|
if (claim && claim.canonical_url) {
|
||||||
|
canonicalSubscriptions.push(claim.canonical_url);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
topLevelComments,
|
||||||
|
commentorUris,
|
||||||
|
unresolvedCommentors,
|
||||||
|
canonicalCommentors,
|
||||||
|
unresolvedSubscriptions,
|
||||||
|
canonicalSubscriptions,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
)((state, uri, maxCount) => `${String(uri)}:${maxCount}`);
|
||||||
|
|
Loading…
Add table
Reference in a new issue