feat(FN-1544): add viewport-gated loading and lightweight memo comparison

- Add viewport-gated fetching to TaskCard component so only visible cards load their data
- Implement lightweight memo comparison to prevent unnecessary re-renders
- Add lazy enable gates to useSessionFiles and useTaskDiffStats hooks with caching
- Add comprehensive tests for useSessionFiles and useTaskDiffStats hooks
- Document viewport-gated loading patterns in memory and dashboard-load performance docs
This commit is contained in:
gsxdsm
2026-04-10 10:44:48 -07:00
parent 14efe1c6a4
commit 9d5b0865b8
8 changed files with 616 additions and 11 deletions

View File

@@ -8,11 +8,39 @@ interface UseSessionFilesResult {
loading: boolean;
}
export function useSessionFiles(taskId: string, worktree: string | undefined, column: string, projectId?: string): UseSessionFilesResult {
interface UseSessionFilesOptions {
/** Enable fetching when true (default). Suppresses fetches for offscreen cards. */
enabled?: boolean;
}
/**
* Fetches session files for tasks with active worktrees.
*
* @param taskId - Task identifier
* @param worktree - Worktree path (undefined = no worktree)
* @param column - Current task column
* @param projectId - Optional project identifier
* @param options.enabled - When false, no fetch is made and returns empty/stable state
*/
export function useSessionFiles(
taskId: string,
worktree: string | undefined,
column: string,
projectId?: string,
options: UseSessionFilesOptions = {},
): UseSessionFilesResult {
const enabled = options.enabled ?? true;
const [files, setFiles] = useState<string[]>([]);
const [loading, setLoading] = useState(false);
useEffect(() => {
// Disabled state: return stable empty state without fetching
if (!enabled) {
setFiles([]);
setLoading(false);
return;
}
if (!taskId || !worktree || !ACTIVE_COLUMNS.has(column)) {
setFiles([]);
setLoading(false);
@@ -40,7 +68,7 @@ export function useSessionFiles(taskId: string, worktree: string | undefined, co
}
void load();
}, [taskId, worktree, column, projectId]);
}, [taskId, worktree, column, projectId, enabled]);
return { files, loading };
}