claimListDiscover: don't re-render until query is done
## Issue 6542 Livestream listing and blocked list kills CLS score This is basically a repeat of what was done on `claimTileDiscover` (homepage), but now on `claimListDiscover` (category pages). This handles the unnecessary re-render when: - the uri list temporarily being zero while waiting for new claim-search results. - livestream claim-search invalidating the list. ## Changes Store the last uri list and use that when we know that claim-search is still not done. ## Tests 1. Ran Lighthouse on category pages (force a livestream channel on it). CLS score must be green. 2. Block `claim_search` from Dev Tools and move to another category. The page should say "timed out" instead of "no results" (i.e. maintain existing behavior).
This commit is contained in:
parent
1994b5da04
commit
50c606d916
1 changed files with 40 additions and 7 deletions
|
@ -141,6 +141,7 @@ function ClaimListDiscover(props: Props) {
|
||||||
const { search } = location;
|
const { search } = location;
|
||||||
const [page, setPage] = React.useState(1);
|
const [page, setPage] = React.useState(1);
|
||||||
const [forceRefresh, setForceRefresh] = React.useState();
|
const [forceRefresh, setForceRefresh] = React.useState();
|
||||||
|
const [finalUris, setFinalUris] = React.useState([]);
|
||||||
const isLargeScreen = useIsLargeScreen();
|
const isLargeScreen = useIsLargeScreen();
|
||||||
const [orderParamEntry, setOrderParamEntry] = usePersistedState(`entry-${location.pathname}`, CS.ORDER_BY_TRENDING);
|
const [orderParamEntry, setOrderParamEntry] = usePersistedState(`entry-${location.pathname}`, CS.ORDER_BY_TRENDING);
|
||||||
const [orderParamUser, setOrderParamUser] = usePersistedState(`orderUser-${location.pathname}`, CS.ORDER_BY_TRENDING);
|
const [orderParamUser, setOrderParamUser] = usePersistedState(`orderUser-${location.pathname}`, CS.ORDER_BY_TRENDING);
|
||||||
|
@ -360,9 +361,10 @@ function ClaimListDiscover(props: Props) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const hasMatureTags = tagsParam && tagsParam.split(',').some((t) => MATURE_TAGS.includes(t));
|
const hasMatureTags = tagsParam && tagsParam.split(',').some((t) => MATURE_TAGS.includes(t));
|
||||||
const claimSearchCacheQuery = createNormalizedClaimSearchKey(options);
|
|
||||||
let claimSearchResult = claimSearchByQuery[claimSearchCacheQuery];
|
const mainSearchKey = createNormalizedClaimSearchKey(options);
|
||||||
const claimSearchResultLastPageReached = claimSearchByQueryLastPageReached[claimSearchCacheQuery];
|
let claimSearchResult = claimSearchByQuery[mainSearchKey];
|
||||||
|
const claimSearchResultLastPageReached = claimSearchByQueryLastPageReached[mainSearchKey];
|
||||||
|
|
||||||
// uncomment to fix an item on a page
|
// uncomment to fix an item on a page
|
||||||
// const fixUri = 'lbry://@corbettreport#0/lbryodysee#5';
|
// const fixUri = 'lbry://@corbettreport#0/lbryodysee#5';
|
||||||
|
@ -380,6 +382,11 @@ function ClaimListDiscover(props: Props) {
|
||||||
// claimSearchResult.splice(2, 0, fixUri);
|
// claimSearchResult.splice(2, 0, fixUri);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
const livestreamSearchKey = liveLivestreamsFirst
|
||||||
|
? createNormalizedClaimSearchKey(getLivestreamOnlyOptions(options))
|
||||||
|
: undefined;
|
||||||
|
const livestreamSearchResult = livestreamSearchKey && claimSearchByQuery[livestreamSearchKey];
|
||||||
|
|
||||||
const [prevOptions, setPrevOptions] = React.useState(null);
|
const [prevOptions, setPrevOptions] = React.useState(null);
|
||||||
|
|
||||||
if (!isJustScrollingToNewPage(prevOptions, options)) {
|
if (!isJustScrollingToNewPage(prevOptions, options)) {
|
||||||
|
@ -482,6 +489,17 @@ function ClaimListDiscover(props: Props) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function urisEqual(prev: Array<string>, next: Array<string>) {
|
||||||
|
if (!prev || !next) {
|
||||||
|
// From 'ClaimList', "null" and "undefined" have special meaning,
|
||||||
|
// so we can't just compare array length here.
|
||||||
|
// - null = "timed out"
|
||||||
|
// - undefined = "no result".
|
||||||
|
return prev === next;
|
||||||
|
}
|
||||||
|
return prev.length === next.length && prev.every((value, index) => value === next[index]);
|
||||||
|
}
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
if (shouldPerformSearch) {
|
if (shouldPerformSearch) {
|
||||||
const searchOptions = JSON.parse(optionsStringForEffect);
|
const searchOptions = JSON.parse(optionsStringForEffect);
|
||||||
|
@ -493,6 +511,21 @@ function ClaimListDiscover(props: Props) {
|
||||||
}
|
}
|
||||||
}, [doClaimSearch, shouldPerformSearch, optionsStringForEffect, forceRefresh]);
|
}, [doClaimSearch, shouldPerformSearch, optionsStringForEffect, forceRefresh]);
|
||||||
|
|
||||||
|
// Resolve 'finalUri'
|
||||||
|
React.useEffect(() => {
|
||||||
|
if (uris) {
|
||||||
|
if (!urisEqual(uris, finalUris)) {
|
||||||
|
setFinalUris(uris);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Wait until all queries are done before updating the uris to avoid layout shifts.
|
||||||
|
const pending = claimSearchResult === undefined || (liveLivestreamsFirst && livestreamSearchResult === undefined);
|
||||||
|
if (!pending && !urisEqual(claimSearchResult, finalUris)) {
|
||||||
|
setFinalUris(claimSearchResult);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [uris, claimSearchResult, finalUris, setFinalUris, liveLivestreamsFirst, livestreamSearchResult]);
|
||||||
|
|
||||||
const headerToUse = header || (
|
const headerToUse = header || (
|
||||||
<ClaimListHeader
|
<ClaimListHeader
|
||||||
channelIds={channelIds}
|
channelIds={channelIds}
|
||||||
|
@ -529,9 +562,9 @@ function ClaimListDiscover(props: Props) {
|
||||||
)}
|
)}
|
||||||
<ClaimList
|
<ClaimList
|
||||||
tileLayout
|
tileLayout
|
||||||
id={claimSearchCacheQuery}
|
id={mainSearchKey}
|
||||||
loading={loading}
|
loading={loading}
|
||||||
uris={uris || claimSearchResult}
|
uris={finalUris}
|
||||||
onScrollBottom={handleScrollBottom}
|
onScrollBottom={handleScrollBottom}
|
||||||
page={page}
|
page={page}
|
||||||
pageSize={dynamicPageSize}
|
pageSize={dynamicPageSize}
|
||||||
|
@ -563,10 +596,10 @@ function ClaimListDiscover(props: Props) {
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<ClaimList
|
<ClaimList
|
||||||
id={claimSearchCacheQuery}
|
id={mainSearchKey}
|
||||||
type={type}
|
type={type}
|
||||||
loading={loading}
|
loading={loading}
|
||||||
uris={uris || claimSearchResult}
|
uris={finalUris}
|
||||||
onScrollBottom={handleScrollBottom}
|
onScrollBottom={handleScrollBottom}
|
||||||
page={page}
|
page={page}
|
||||||
pageSize={dynamicPageSize}
|
pageSize={dynamicPageSize}
|
||||||
|
|
Loading…
Add table
Reference in a new issue