perf(renderer): skip stable sidebar task group renders
This commit is contained in:
parent
b6ea569623
commit
36939d428a
1 changed files with 117 additions and 10 deletions
|
|
@ -463,6 +463,69 @@ interface TaskRowsProps {
|
||||||
getOwnerColorName: TaskOwnerColorResolver;
|
getOwnerColorName: TaskOwnerColorResolver;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type TaskRowsDerivedProps = Pick<
|
||||||
|
TaskRowsProps,
|
||||||
|
| 'tasks'
|
||||||
|
| 'visibleCount'
|
||||||
|
| 'isPinned'
|
||||||
|
| 'isArchived'
|
||||||
|
| 'isNewTask'
|
||||||
|
| 'isTeamOffline'
|
||||||
|
| 'pinnedOverride'
|
||||||
|
| 'archivedOverride'
|
||||||
|
| 'getDisplaySubject'
|
||||||
|
| 'getOwnerColorName'
|
||||||
|
>;
|
||||||
|
|
||||||
|
function getTaskRowsVisibleTasks(
|
||||||
|
props: Pick<TaskRowsProps, 'tasks' | 'visibleCount'>
|
||||||
|
): GlobalTask[] {
|
||||||
|
return typeof props.visibleCount === 'number'
|
||||||
|
? props.tasks.slice(0, props.visibleCount)
|
||||||
|
: props.tasks;
|
||||||
|
}
|
||||||
|
|
||||||
|
function resolveTaskBooleanState(
|
||||||
|
override: boolean | undefined,
|
||||||
|
resolver: TaskBooleanResolver,
|
||||||
|
task: GlobalTask
|
||||||
|
): boolean {
|
||||||
|
return override ?? resolver(task.teamName, task.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
function areTaskRowsDerivedValuesEqual(
|
||||||
|
prev: TaskRowsDerivedProps,
|
||||||
|
next: TaskRowsDerivedProps
|
||||||
|
): boolean {
|
||||||
|
const prevVisibleTasks = getTaskRowsVisibleTasks(prev);
|
||||||
|
const nextVisibleTasks = getTaskRowsVisibleTasks(next);
|
||||||
|
if (!areTaskSidebarArraysEqual(prevVisibleTasks, nextVisibleTasks)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let index = 0; index < prevVisibleTasks.length; index += 1) {
|
||||||
|
const prevTask = prevVisibleTasks[index];
|
||||||
|
const nextTask = nextVisibleTasks[index];
|
||||||
|
if (!prevTask || !nextTask) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
resolveTaskBooleanState(prev.pinnedOverride, prev.isPinned, prevTask) !==
|
||||||
|
resolveTaskBooleanState(next.pinnedOverride, next.isPinned, nextTask) ||
|
||||||
|
resolveTaskBooleanState(prev.archivedOverride, prev.isArchived, prevTask) !==
|
||||||
|
resolveTaskBooleanState(next.archivedOverride, next.isArchived, nextTask) ||
|
||||||
|
prev.isNewTask(prevTask) !== next.isNewTask(nextTask) ||
|
||||||
|
prev.isTeamOffline(prevTask.teamName) !== next.isTeamOffline(nextTask.teamName) ||
|
||||||
|
prev.getDisplaySubject(prevTask) !== next.getDisplaySubject(nextTask) ||
|
||||||
|
prev.getOwnerColorName(prevTask) !== next.getOwnerColorName(nextTask)
|
||||||
|
) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
const TaskRows = memo(function TaskRows({
|
const TaskRows = memo(function TaskRows({
|
||||||
tasks,
|
tasks,
|
||||||
visibleCount,
|
visibleCount,
|
||||||
|
|
@ -540,13 +603,41 @@ const TaskRows = memo(function TaskRows({
|
||||||
})}
|
})}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
});
|
}, areTaskRowsPropsEqual);
|
||||||
|
|
||||||
function areTaskReferencesEqual(prev: readonly GlobalTask[], next: readonly GlobalTask[]): boolean {
|
function areTaskRowsPropsEqual(prev: TaskRowsProps, next: TaskRowsProps): boolean {
|
||||||
|
return (
|
||||||
|
prev.visibleCount === next.visibleCount &&
|
||||||
|
prev.keyPrefix === next.keyPrefix &&
|
||||||
|
prev.hideTeamName === next.hideTeamName &&
|
||||||
|
prev.hideProjectName === next.hideProjectName &&
|
||||||
|
prev.showTeamName === next.showTeamName &&
|
||||||
|
prev.showTeamHeader === next.showTeamHeader &&
|
||||||
|
prev.pinnedOverride === next.pinnedOverride &&
|
||||||
|
prev.archivedOverride === next.archivedOverride &&
|
||||||
|
prev.formatTeamHeader === next.formatTeamHeader &&
|
||||||
|
prev.renamingKey === next.renamingKey &&
|
||||||
|
prev.onTogglePin === next.onTogglePin &&
|
||||||
|
prev.onToggleArchive === next.onToggleArchive &&
|
||||||
|
prev.onMarkUnread === next.onMarkUnread &&
|
||||||
|
prev.onRename === next.onRename &&
|
||||||
|
prev.onDelete === next.onDelete &&
|
||||||
|
prev.onRenameComplete === next.onRenameComplete &&
|
||||||
|
prev.onRenameCancel === next.onRenameCancel &&
|
||||||
|
areTaskRowsDerivedValuesEqual(prev, next)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function areTaskSidebarArraysEqual(
|
||||||
|
prev: readonly GlobalTask[],
|
||||||
|
next: readonly GlobalTask[]
|
||||||
|
): boolean {
|
||||||
if (prev === next) return true;
|
if (prev === next) return true;
|
||||||
if (prev.length !== next.length) return false;
|
if (prev.length !== next.length) return false;
|
||||||
for (let i = 0; i < prev.length; i += 1) {
|
for (let i = 0; i < prev.length; i += 1) {
|
||||||
if (prev[i] !== next[i]) return false;
|
if (!taskSidebarFieldsEqual(prev[i], next[i])) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -706,16 +797,12 @@ const ProjectTaskGroup = memo(
|
||||||
(prev, next) =>
|
(prev, next) =>
|
||||||
prev.group.projectKey === next.group.projectKey &&
|
prev.group.projectKey === next.group.projectKey &&
|
||||||
prev.group.projectLabel === next.group.projectLabel &&
|
prev.group.projectLabel === next.group.projectLabel &&
|
||||||
areTaskReferencesEqual(prev.group.tasks, next.group.tasks) &&
|
areTaskSidebarArraysEqual(prev.group.tasks, next.group.tasks) &&
|
||||||
prev.isCollapsed === next.isCollapsed &&
|
prev.isCollapsed === next.isCollapsed &&
|
||||||
prev.visibleCount === next.visibleCount &&
|
prev.visibleCount === next.visibleCount &&
|
||||||
prev.noProjectGroupColor === next.noProjectGroupColor &&
|
prev.noProjectGroupColor === next.noProjectGroupColor &&
|
||||||
prev.showMoreLabel === next.showMoreLabel &&
|
prev.showMoreLabel === next.showMoreLabel &&
|
||||||
prev.showLessLabel === next.showLessLabel &&
|
prev.showLessLabel === next.showLessLabel &&
|
||||||
prev.isPinned === next.isPinned &&
|
|
||||||
prev.isArchived === next.isArchived &&
|
|
||||||
prev.isNewTask === next.isNewTask &&
|
|
||||||
prev.isTeamOffline === next.isTeamOffline &&
|
|
||||||
prev.renamingKey === next.renamingKey &&
|
prev.renamingKey === next.renamingKey &&
|
||||||
prev.formatTeamHeader === next.formatTeamHeader &&
|
prev.formatTeamHeader === next.formatTeamHeader &&
|
||||||
prev.onToggleGroup === next.onToggleGroup &&
|
prev.onToggleGroup === next.onToggleGroup &&
|
||||||
|
|
@ -727,8 +814,28 @@ const ProjectTaskGroup = memo(
|
||||||
prev.onDelete === next.onDelete &&
|
prev.onDelete === next.onDelete &&
|
||||||
prev.onRenameComplete === next.onRenameComplete &&
|
prev.onRenameComplete === next.onRenameComplete &&
|
||||||
prev.onRenameCancel === next.onRenameCancel &&
|
prev.onRenameCancel === next.onRenameCancel &&
|
||||||
prev.getDisplaySubject === next.getDisplaySubject &&
|
areTaskRowsDerivedValuesEqual(
|
||||||
prev.getOwnerColorName === next.getOwnerColorName
|
{
|
||||||
|
tasks: prev.group.tasks,
|
||||||
|
visibleCount: prev.visibleCount,
|
||||||
|
isPinned: prev.isPinned,
|
||||||
|
isArchived: prev.isArchived,
|
||||||
|
isNewTask: prev.isNewTask,
|
||||||
|
isTeamOffline: prev.isTeamOffline,
|
||||||
|
getDisplaySubject: prev.getDisplaySubject,
|
||||||
|
getOwnerColorName: prev.getOwnerColorName,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
tasks: next.group.tasks,
|
||||||
|
visibleCount: next.visibleCount,
|
||||||
|
isPinned: next.isPinned,
|
||||||
|
isArchived: next.isArchived,
|
||||||
|
isNewTask: next.isNewTask,
|
||||||
|
isTeamOffline: next.isTeamOffline,
|
||||||
|
getDisplaySubject: next.getDisplaySubject,
|
||||||
|
getOwnerColorName: next.getOwnerColorName,
|
||||||
|
}
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
export const GlobalTaskList = memo(function GlobalTaskList({
|
export const GlobalTaskList = memo(function GlobalTaskList({
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue