perf(renderer): cache repeated team badge selectors
This commit is contained in:
parent
93a45e0823
commit
5041c79916
3 changed files with 35 additions and 1 deletions
|
|
@ -210,12 +210,14 @@ interface SidebarTeamsDerived {
|
|||
}
|
||||
|
||||
let cachedSidebarTeamsSignature: string | null = null;
|
||||
let cachedSidebarTeamsSource: readonly TeamSummary[] | null = null;
|
||||
let cachedSidebarTeamsDerived: SidebarTeamsDerived = {
|
||||
identityKey: '',
|
||||
filterTeams: [],
|
||||
statusSummaries: [],
|
||||
memberColorByTeam: new Map(),
|
||||
};
|
||||
let cachedLeadOfflineTeamsSource: Partial<Record<string, LeadActivityState>> | null = null;
|
||||
let cachedLeadOfflineTeamsSignature = '';
|
||||
let cachedLeadOfflineTeamNames: string[] = [];
|
||||
|
||||
|
|
@ -255,6 +257,10 @@ function buildTeamNamesIdentityKey(teams: readonly TeamSummary[]): string {
|
|||
function selectLeadOfflineTeamNames(
|
||||
leadActivityByTeam: Partial<Record<string, LeadActivityState>>
|
||||
): string[] {
|
||||
if (leadActivityByTeam === cachedLeadOfflineTeamsSource) {
|
||||
return cachedLeadOfflineTeamNames;
|
||||
}
|
||||
|
||||
const offlineTeamNames: string[] = [];
|
||||
for (const [teamName, activity] of Object.entries(leadActivityByTeam)) {
|
||||
if (activity === 'offline') {
|
||||
|
|
@ -269,17 +275,24 @@ function selectLeadOfflineTeamNames(
|
|||
}
|
||||
|
||||
if (signature === cachedLeadOfflineTeamsSignature) {
|
||||
cachedLeadOfflineTeamsSource = leadActivityByTeam;
|
||||
return cachedLeadOfflineTeamNames;
|
||||
}
|
||||
|
||||
cachedLeadOfflineTeamsSource = leadActivityByTeam;
|
||||
cachedLeadOfflineTeamsSignature = signature;
|
||||
cachedLeadOfflineTeamNames = offlineTeamNames;
|
||||
return cachedLeadOfflineTeamNames;
|
||||
}
|
||||
|
||||
function selectSidebarTeamsDerived(teams: readonly TeamSummary[]): SidebarTeamsDerived {
|
||||
if (teams === cachedSidebarTeamsSource) {
|
||||
return cachedSidebarTeamsDerived;
|
||||
}
|
||||
|
||||
const signature = buildSidebarTeamsSignature(teams);
|
||||
if (signature === cachedSidebarTeamsSignature) {
|
||||
cachedSidebarTeamsSource = teams;
|
||||
return cachedSidebarTeamsDerived;
|
||||
}
|
||||
|
||||
|
|
@ -290,6 +303,7 @@ function selectSidebarTeamsDerived(teams: readonly TeamSummary[]): SidebarTeamsD
|
|||
}
|
||||
}
|
||||
|
||||
cachedSidebarTeamsSource = teams;
|
||||
cachedSidebarTeamsSignature = signature;
|
||||
cachedSidebarTeamsDerived = {
|
||||
identityKey: buildTeamNamesIdentityKey(teams),
|
||||
|
|
|
|||
|
|
@ -34,6 +34,18 @@ interface MemberBadgeProps {
|
|||
}
|
||||
|
||||
const EMPTY_TEAM_MEMBERS: readonly ResolvedTeamMember[] = [];
|
||||
const memberAvatarMapCache = new WeakMap<readonly ResolvedTeamMember[], Map<string, string>>();
|
||||
|
||||
function getCachedMemberAvatarMap(members: readonly ResolvedTeamMember[]): Map<string, string> {
|
||||
const cached = memberAvatarMapCache.get(members);
|
||||
if (cached) {
|
||||
return cached;
|
||||
}
|
||||
|
||||
const next = buildMemberAvatarMap(members);
|
||||
memberAvatarMapCache.set(members, next);
|
||||
return next;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reusable member avatar + colored name badge.
|
||||
|
|
@ -61,7 +73,7 @@ export const MemberBadge = memo(
|
|||
? selectResolvedMembersForTeamName(s, effectiveAvatarTeamName)
|
||||
: EMPTY_TEAM_MEMBERS
|
||||
);
|
||||
const avatarMap = useMemo(() => buildMemberAvatarMap(teamMembers), [teamMembers]);
|
||||
const avatarMap = useMemo(() => getCachedMemberAvatarMap(teamMembers), [teamMembers]);
|
||||
const avatarSize = size === 'md' ? 32 : size === 'sm' ? 24 : 18;
|
||||
const avatarClass = size === 'md' ? 'size-6' : size === 'sm' ? 'size-5' : 'size-4';
|
||||
const textClass = size === 'md' ? 'text-xs' : size === 'sm' ? 'text-[10px]' : 'text-[9px]';
|
||||
|
|
|
|||
|
|
@ -114,6 +114,7 @@ interface TeamMentionEntry {
|
|||
}
|
||||
|
||||
let cachedTeamMentionSignature = '';
|
||||
let cachedTeamMentionSource: readonly TeamSummary[] | null = null;
|
||||
let cachedTeamMentionMeta: TeamMentionMeta = {
|
||||
teamNames: EMPTY_TEAM_NAMES,
|
||||
teamColorByName: EMPTY_TEAM_COLOR_MAP,
|
||||
|
|
@ -142,8 +143,13 @@ function getTeamMentionSignature(teams: readonly TeamSummary[]): string {
|
|||
}
|
||||
|
||||
function selectMessagesPanelTeamMentionMeta(teams: readonly TeamSummary[]): TeamMentionMeta {
|
||||
if (teams === cachedTeamMentionSource) {
|
||||
return cachedTeamMentionMeta;
|
||||
}
|
||||
|
||||
const signature = getTeamMentionSignature(teams);
|
||||
if (signature === cachedTeamMentionSignature) {
|
||||
cachedTeamMentionSource = teams;
|
||||
return cachedTeamMentionMeta;
|
||||
}
|
||||
|
||||
|
|
@ -157,6 +163,7 @@ function selectMessagesPanelTeamMentionMeta(teams: readonly TeamSummary[]): Team
|
|||
.sort(compareTeamMentionEntries);
|
||||
|
||||
if (entries.length === 0) {
|
||||
cachedTeamMentionSource = teams;
|
||||
cachedTeamMentionSignature = signature;
|
||||
cachedTeamMentionMeta = {
|
||||
teamNames: EMPTY_TEAM_NAMES,
|
||||
|
|
@ -180,6 +187,7 @@ function selectMessagesPanelTeamMentionMeta(teams: readonly TeamSummary[]): Team
|
|||
}
|
||||
}
|
||||
|
||||
cachedTeamMentionSource = teams;
|
||||
cachedTeamMentionSignature = signature;
|
||||
cachedTeamMentionMeta = { teamNames, teamColorByName };
|
||||
return cachedTeamMentionMeta;
|
||||
|
|
|
|||
Loading…
Reference in a new issue