Fix sidebar subs inefficiencies
- `filteredSubscriptions` was running the filter code whether or not it actually required filtering, because the `!subscriptionFilter` logic is placed in the predicate. While it is a clean one-liner, it is slow when the subs list is huge. - While at it, moved the code into `getSubscriptionSection` to isolate things. - The sidebar was resolving the entire subs list, which is super slow for a list of 500+. Since we now have a "Manage Subscriptions" page, just batch-resolve the N visible subs. - TODO: the code should probably be moved from 'app' to 'sideNavigate'.
This commit is contained in:
parent
3edb00b99d
commit
6c76cff2a0
3 changed files with 20 additions and 17 deletions
|
@ -23,6 +23,7 @@ import usePersistedState from 'effects/use-persisted-state';
|
|||
import useConnectionStatus from 'effects/use-connection-status';
|
||||
import Spinner from 'component/spinner';
|
||||
import LANGUAGES from 'constants/languages';
|
||||
import { SIDEBAR_SUBS_DISPLAYED } from 'constants/subscriptions';
|
||||
import YoutubeWelcome from 'web/component/youtubeReferralWelcome';
|
||||
import {
|
||||
useDegradedPerformance,
|
||||
|
@ -477,7 +478,7 @@ function App(props: Props) {
|
|||
useLayoutEffect(() => {
|
||||
if (sidebarOpen && isPersonalized && subscriptions && !resolvedSubscriptions) {
|
||||
setResolvedSubscriptions(true);
|
||||
resolveUris(subscriptions.map((sub) => sub.uri));
|
||||
resolveUris(subscriptions.slice(0, SIDEBAR_SUBS_DISPLAYED).map((sub) => sub.uri));
|
||||
}
|
||||
}, [sidebarOpen, isPersonalized, resolvedSubscriptions, subscriptions, resolveUris, setResolvedSubscriptions]);
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ import type { Node } from 'react';
|
|||
import * as PAGES from 'constants/pages';
|
||||
import * as ICONS from 'constants/icons';
|
||||
import * as KEYCODES from 'constants/keycodes';
|
||||
import { SIDEBAR_SUBS_DISPLAYED } from 'constants/subscriptions';
|
||||
import React, { useEffect } from 'react';
|
||||
import Button from 'component/button';
|
||||
import ClaimPreviewTitle from 'component/claimPreviewTitle';
|
||||
|
@ -16,7 +17,6 @@ import { useIsMobile, useIsLargeScreen, isTouch } from 'effects/use-screensize';
|
|||
import { GetLinksData } from 'util/buildHomepage';
|
||||
import { DOMAIN, ENABLE_UI_NOTIFICATIONS, ENABLE_NO_SOURCE_CLAIMS, CHANNEL_STAKED_LEVEL_LIVESTREAM } from 'config';
|
||||
|
||||
const FOLLOWED_ITEM_INITIAL_LIMIT = 10;
|
||||
const touch = isTouch();
|
||||
|
||||
type SideNavLink = {
|
||||
|
@ -265,23 +265,13 @@ function SideNavigation(props: Props) {
|
|||
const showPushMenu = sidebarOpen && !menuCanCloseCompletely;
|
||||
const showOverlay = isAbsolute && sidebarOpen;
|
||||
|
||||
const showSubscriptionSection = shouldRenderLargeMenu && isPersonalized && subscriptions && subscriptions.length > 0;
|
||||
const showTagSection = sidebarOpen && isPersonalized && followedTags && followedTags.length;
|
||||
|
||||
const [subscriptionFilter, setSubscriptionFilter] = React.useState('');
|
||||
|
||||
const filteredSubscriptions = subscriptions.filter(
|
||||
(sub) => !subscriptionFilter || sub.channelName.toLowerCase().includes(subscriptionFilter.toLowerCase())
|
||||
);
|
||||
|
||||
let displayedSubscriptions = filteredSubscriptions;
|
||||
if (showSubscriptionSection && !subscriptionFilter && subscriptions.length > FOLLOWED_ITEM_INITIAL_LIMIT) {
|
||||
displayedSubscriptions = subscriptions.slice(0, FOLLOWED_ITEM_INITIAL_LIMIT);
|
||||
}
|
||||
|
||||
let displayedFollowedTags = followedTags;
|
||||
if (showTagSection && followedTags.length > FOLLOWED_ITEM_INITIAL_LIMIT && !expandTags) {
|
||||
displayedFollowedTags = followedTags.slice(0, FOLLOWED_ITEM_INITIAL_LIMIT);
|
||||
if (showTagSection && followedTags.length > SIDEBAR_SUBS_DISPLAYED && !expandTags) {
|
||||
displayedFollowedTags = followedTags.slice(0, SIDEBAR_SUBS_DISPLAYED);
|
||||
}
|
||||
|
||||
function getLink(props: SideNavLink) {
|
||||
|
@ -312,11 +302,20 @@ function SideNavigation(props: Props) {
|
|||
}
|
||||
|
||||
function getSubscriptionSection() {
|
||||
if (showSubscriptionSection) {
|
||||
const showSubsSection = shouldRenderLargeMenu && isPersonalized && subscriptions && subscriptions.length > 0;
|
||||
if (showSubsSection) {
|
||||
let displayedSubscriptions;
|
||||
if (subscriptionFilter) {
|
||||
const filter = subscriptionFilter.toLowerCase();
|
||||
displayedSubscriptions = subscriptions.filter((sub) => sub.channelName.toLowerCase().includes(filter));
|
||||
} else {
|
||||
displayedSubscriptions = subscriptions.slice(0, SIDEBAR_SUBS_DISPLAYED);
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<ul className="navigation__secondary navigation-links">
|
||||
{subscriptions.length > FOLLOWED_ITEM_INITIAL_LIMIT && (
|
||||
{subscriptions.length > SIDEBAR_SUBS_DISPLAYED && (
|
||||
<li className="navigation-item">
|
||||
<DebouncedInput icon={ICONS.SEARCH} placeholder={__('Filter')} onChange={setSubscriptionFilter} />
|
||||
</li>
|
||||
|
@ -356,7 +355,7 @@ function SideNavigation(props: Props) {
|
|||
<Button navigate={`/$/discover?t=${name}`} label={`#${name}`} className="navigation-link" />
|
||||
</li>
|
||||
))}
|
||||
{followedTags.length > FOLLOWED_ITEM_INITIAL_LIMIT && (
|
||||
{followedTags.length > SIDEBAR_SUBS_DISPLAYED && (
|
||||
<Button
|
||||
key="showMore"
|
||||
label={expandTags ? __('Show less') : __('Show more')}
|
||||
|
|
|
@ -10,3 +10,6 @@ export const NOTIFY_ONLY = 'NOTIFY_ONLY;';
|
|||
export const SUGGESTED_TOP_BID = 'top_bid';
|
||||
export const SUGGESTED_TOP_SUBSCRIBED = 'top_subscribed';
|
||||
export const SUGGESTED_FEATURED = 'featured';
|
||||
|
||||
// Sidebar UI
|
||||
export const SIDEBAR_SUBS_DISPLAYED = 10;
|
||||
|
|
Loading…
Reference in a new issue