From b5320defd17a7ee882be50e3c52ea805805cf5c3 Mon Sep 17 00:00:00 2001 From: David Kaltschmidt Date: Fri, 5 Dec 2025 17:27:23 +0100 Subject: [PATCH] Refactor: Defer state updates and simplify query time handling in PanelPerformanceMetrics This commit refines the PanelPerformanceMetrics component by deferring state updates to avoid React warnings during rendering. It also simplifies the handling of query time by removing the fake timer logic, directly using the last query time for display. Additionally, the polling for profiling state changes is adjusted to run once, improving performance and reducing unnecessary re-renders. --- eslint-suppressions.json | 2 +- .../scene/PanelPerformanceMetrics.tsx | 66 +++++-------------- 2 files changed, 19 insertions(+), 49 deletions(-) diff --git a/eslint-suppressions.json b/eslint-suppressions.json index f90a21cb7c5..96fa771540d 100644 --- a/eslint-suppressions.json +++ b/eslint-suppressions.json @@ -4677,4 +4677,4 @@ "count": 1 } } -} +} \ No newline at end of file diff --git a/public/app/features/dashboard-scene/scene/PanelPerformanceMetrics.tsx b/public/app/features/dashboard-scene/scene/PanelPerformanceMetrics.tsx index 9e4cd149f63..2eb52065970 100644 --- a/public/app/features/dashboard-scene/scene/PanelPerformanceMetrics.tsx +++ b/public/app/features/dashboard-scene/scene/PanelPerformanceMetrics.tsx @@ -38,10 +38,13 @@ export class PanelPerformanceMetrics extends SceneObjectBase { - this.setState({ metrics: updatedMetrics }); + // Defer state update to avoid React warning about updating during render + setTimeout(() => { + this.setState({ metrics: updatedMetrics }); + }, 0); }) ); }; @@ -68,17 +71,21 @@ function PanelPerformanceMetricsRenderer({ model }: SceneComponentProps(null); - const startTimeRef = useRef(null); + const profilingStateRef = useRef(isProfilingEnabled); + + // Update ref when state changes + useEffect(() => { + profilingStateRef.current = isProfilingEnabled; + }, [isProfilingEnabled]); // Watch for profiling state changes (when toggled via hotkey) useEffect(() => { // Poll for profiling state changes - this allows the component to react when profiling is toggled const checkProfilingState = () => { const currentState = isPanelProfilingEnabled(); - if (currentState !== isProfilingEnabled) { + // Compare against ref to avoid stale closure + if (currentState !== profilingStateRef.current) { setIsProfilingEnabled(currentState); } }; @@ -88,7 +95,7 @@ function PanelPerformanceMetricsRenderer({ model }: SceneComponentProps clearInterval(interval); - }, [isProfilingEnabled]); + }, []); // Empty dependency array - polling should run once and persist // Get last operation times (most recent operation in each array) const lastQueryTime = @@ -104,44 +111,7 @@ function PanelPerformanceMetricsRenderer({ model }: SceneComponentProps { - // If we have a real query time, stop the fake timer - if (lastQueryTime > 0) { - if (intervalRef.current) { - clearInterval(intervalRef.current); - intervalRef.current = null; - } - setFakeQueryTime(0); - startTimeRef.current = null; - return; - } - - // If no query operations yet, start the fake timer - if (metrics && metrics.queryOperations.length === 0) { - // Start timer if not already running - if (!intervalRef.current) { - startTimeRef.current = Date.now(); - intervalRef.current = setInterval(() => { - if (startTimeRef.current) { - setFakeQueryTime(Date.now() - startTimeRef.current); - } - }, 166); // Update every 166ms for smooth counting - } - } - - // Cleanup on unmount - return () => { - if (intervalRef.current) { - clearInterval(intervalRef.current); - intervalRef.current = null; - } - }; - }, [lastQueryTime, metrics]); - - // Use fake query time if real one is 0 - const displayQueryTime = lastQueryTime > 0 ? lastQueryTime : fakeQueryTime; - const lastTotalTime = displayQueryTime + lastRenderTime + lastTransformTime; + const lastTotalTime = lastQueryTime + lastRenderTime + lastTransformTime; // Don't render if panel is not available if (!panel) { @@ -169,7 +139,7 @@ function PanelPerformanceMetricsRenderer({ model }: SceneComponentProps - {renderMetricRow('Query', displayQueryTime)} + {renderMetricRow('Query', lastQueryTime)} {hasTransformations && renderMetricRow('Transform', lastTransformTime)} {renderMetricRow('Render', lastRenderTime)}
@@ -184,14 +154,14 @@ function PanelPerformanceMetricsRenderer({ model }: SceneComponentProps 0 && `Q:${formatDuration(displayQueryTime)}`, + lastQueryTime > 0 && `Q:${formatDuration(lastQueryTime)}`, lastTransformTime > 0 && `T:${formatDuration(lastTransformTime)}`, lastRenderTime > 0 && `R:${formatDuration(lastRenderTime)}`, ]