Remove dashboard-load timing instrumentation
The perf logs were temporary diagnostics used to identify that slow reloads were caused by a registered remote node timing out in /projects/across-nodes. Root cause is resolved and the short-circuit for zero-remote setups (already committed in 7ea60382a) remains. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
import { useState, useCallback, useEffect, useMemo, useRef } from "react";
|
import { useState, useCallback, useEffect, useMemo } from "react";
|
||||||
import type { Task, TaskDetail } from "@fusion/core";
|
import type { Task, TaskDetail } from "@fusion/core";
|
||||||
import { Header, useViewportMode } from "./components/Header";
|
import { Header, useViewportMode } from "./components/Header";
|
||||||
import { Board } from "./components/Board";
|
import { Board } from "./components/Board";
|
||||||
@@ -49,7 +49,7 @@ import { useRemoteNodeData } from "./hooks/useRemoteNodeData";
|
|||||||
import { useRemoteNodeEvents } from "./hooks/useRemoteNodeEvents";
|
import { useRemoteNodeEvents } from "./hooks/useRemoteNodeEvents";
|
||||||
import { NodeProvider, useNodeContext } from "./context/NodeContext";
|
import { NodeProvider, useNodeContext } from "./context/NodeContext";
|
||||||
import type { AiSessionSummary } from "./api";
|
import type { AiSessionSummary } from "./api";
|
||||||
import { fetchAiSession, fetchUnreadCount, reportDashboardPerf } from "./api";
|
import { fetchAiSession, fetchUnreadCount } from "./api";
|
||||||
|
|
||||||
function AppInner() {
|
function AppInner() {
|
||||||
const { toasts, addToast, removeToast } = useToast();
|
const { toasts, addToast, removeToast } = useToast();
|
||||||
@@ -133,9 +133,6 @@ function AppInner() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const [initialLoadComplete, setInitialLoadComplete] = useState(false);
|
const [initialLoadComplete, setInitialLoadComplete] = useState(false);
|
||||||
const mountTimeRef = useRef(performance.now());
|
|
||||||
const projectsReadyLoggedRef = useRef(false);
|
|
||||||
const projectReadyLoggedRef = useRef(false);
|
|
||||||
|
|
||||||
const loadingStage = useMemo<DashboardLoaderStage>(() => {
|
const loadingStage = useMemo<DashboardLoaderStage>(() => {
|
||||||
if (projectsLoading) return "projects";
|
if (projectsLoading) return "projects";
|
||||||
@@ -143,21 +140,6 @@ function AppInner() {
|
|||||||
return "tasks";
|
return "tasks";
|
||||||
}, [projectsLoading, currentProjectLoading]);
|
}, [projectsLoading, currentProjectLoading]);
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (!projectsLoading && !projectsReadyLoggedRef.current) {
|
|
||||||
projectsReadyLoggedRef.current = true;
|
|
||||||
const msg = `projects loaded at ${Math.round(performance.now() - mountTimeRef.current)}ms from mount`;
|
|
||||||
console.log(`[App] ${msg}`);
|
|
||||||
reportDashboardPerf("[App]", msg);
|
|
||||||
}
|
|
||||||
if (!currentProjectLoading && !projectReadyLoggedRef.current) {
|
|
||||||
projectReadyLoggedRef.current = true;
|
|
||||||
const msg = `current-project resolved at ${Math.round(performance.now() - mountTimeRef.current)}ms from mount`;
|
|
||||||
console.log(`[App] ${msg}`);
|
|
||||||
reportDashboardPerf("[App]", msg);
|
|
||||||
}
|
|
||||||
}, [projectsLoading, currentProjectLoading]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (initialLoadComplete) {
|
if (initialLoadComplete) {
|
||||||
return;
|
return;
|
||||||
@@ -167,11 +149,7 @@ function AppInner() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const settleStart = performance.now();
|
|
||||||
const settleTimer = window.setTimeout(() => {
|
const settleTimer = window.setTimeout(() => {
|
||||||
const msg = `dashboard ready at ${Math.round(performance.now() - mountTimeRef.current)}ms from mount (settle delay=${Math.round(performance.now() - settleStart)}ms)`;
|
|
||||||
console.log(`[App] ${msg}`);
|
|
||||||
reportDashboardPerf("[App]", msg);
|
|
||||||
setInitialLoadComplete(true);
|
setInitialLoadComplete(true);
|
||||||
}, 200);
|
}, 200);
|
||||||
|
|
||||||
|
|||||||
@@ -3454,19 +3454,6 @@ export function fetchProjectsAcrossNodes(): Promise<ProjectInfoWithSource[]> {
|
|||||||
return api<ProjectInfoWithSource[]>("/projects/across-nodes");
|
return api<ProjectInfoWithSource[]>("/projects/across-nodes");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Append a client-side perf measurement to the shared dashboard-perf log on disk.
|
|
||||||
* Used when browser devtools aren't available (e.g. mobile). Best-effort.
|
|
||||||
*/
|
|
||||||
export function reportDashboardPerf(source: string, message: string): void {
|
|
||||||
void api("/_perf/dashboard-load", {
|
|
||||||
method: "POST",
|
|
||||||
body: JSON.stringify({ source, message }),
|
|
||||||
}).catch(() => {
|
|
||||||
// best-effort only
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Fetch all registered nodes */
|
/** Fetch all registered nodes */
|
||||||
export function fetchNodes(): Promise<NodeInfo[]> {
|
export function fetchNodes(): Promise<NodeInfo[]> {
|
||||||
return api<NodeInfo[]>("/nodes");
|
return api<NodeInfo[]>("/nodes");
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ import type { ProjectInfo } from "../api";
|
|||||||
import {
|
import {
|
||||||
fetchProjectsAcrossNodes,
|
fetchProjectsAcrossNodes,
|
||||||
registerProject,
|
registerProject,
|
||||||
reportDashboardPerf,
|
|
||||||
unregisterProject,
|
unregisterProject,
|
||||||
updateProject,
|
updateProject,
|
||||||
type ProjectCreateInput,
|
type ProjectCreateInput,
|
||||||
@@ -60,22 +59,13 @@ export function useProjects(): UseProjectsResult {
|
|||||||
|
|
||||||
async function load() {
|
async function load() {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
const t0 = performance.now();
|
|
||||||
try {
|
try {
|
||||||
const data = await fetchProjectsAcrossNodes();
|
const data = await fetchProjectsAcrossNodes();
|
||||||
const elapsed = Math.round(performance.now() - t0);
|
|
||||||
const msg = `initial fetchProjectsAcrossNodes took ${elapsed}ms (${data.length} projects)`;
|
|
||||||
console.log(`[useProjects] ${msg}`);
|
|
||||||
reportDashboardPerf("[useProjects]", msg);
|
|
||||||
if (!cancelled) {
|
if (!cancelled) {
|
||||||
setProjects(data);
|
setProjects(data);
|
||||||
setError(null);
|
setError(null);
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
const elapsed = Math.round(performance.now() - t0);
|
|
||||||
const msg = `initial fetch failed after ${elapsed}ms: ${err instanceof Error ? err.message : String(err)}`;
|
|
||||||
console.warn(`[useProjects] ${msg}`);
|
|
||||||
reportDashboardPerf("[useProjects]", msg);
|
|
||||||
if (!cancelled) {
|
if (!cancelled) {
|
||||||
setError(err instanceof Error ? err.message : "Failed to fetch projects");
|
setError(err instanceof Error ? err.message : "Failed to fetch projects");
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user