From 10cf557b11cf5a772c29c5c529eb8d12fb94dad0 Mon Sep 17 00:00:00 2001 From: "2569718930@qq.com" <2569718930@qq.com> Date: Mon, 1 Jun 2026 02:56:13 +0800 Subject: [PATCH] Batch deferred chart detail loads --- .../scan-terminal/LiveTemperatureThresholdChart.tsx | 8 ++++++-- .../__tests__/refreshCadencePolicy.test.ts | 12 ++++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/frontend/components/dashboard/scan-terminal/LiveTemperatureThresholdChart.tsx b/frontend/components/dashboard/scan-terminal/LiveTemperatureThresholdChart.tsx index 88cdcf12..80735141 100644 --- a/frontend/components/dashboard/scan-terminal/LiveTemperatureThresholdChart.tsx +++ b/frontend/components/dashboard/scan-terminal/LiveTemperatureThresholdChart.tsx @@ -60,7 +60,8 @@ const FOREGROUND_FULL_DETAIL_REFRESH_DEDUP_MS = 90_000; const DETAIL_LOAD_BATCH_DELAY_MS = 0; const INITIAL_DETAIL_LOAD_SLOTS = 3; const DEFERRED_DETAIL_LOAD_DELAY_MS = 1_200; -const DEFERRED_DETAIL_LOAD_STEP_MS = 450; +const DEFERRED_DETAIL_LOAD_GROUP_SIZE = 3; +const DEFERRED_DETAIL_LOAD_WAVE_STEP_MS = 900; const TemperatureChartCanvas = dynamic( () => @@ -157,7 +158,10 @@ function getInitialDetailLoadDelayMs({ if (!compact || isActive || isMaximized) return 0; const normalizedIndex = normalizeSlotIndex(slotIndex); if (normalizedIndex < INITIAL_DETAIL_LOAD_SLOTS) return 0; - return DEFERRED_DETAIL_LOAD_DELAY_MS + (normalizedIndex - INITIAL_DETAIL_LOAD_SLOTS) * DEFERRED_DETAIL_LOAD_STEP_MS; + const deferredWave = Math.floor( + (normalizedIndex - INITIAL_DETAIL_LOAD_SLOTS) / DEFERRED_DETAIL_LOAD_GROUP_SIZE, + ); + return DEFERRED_DETAIL_LOAD_DELAY_MS + deferredWave * DEFERRED_DETAIL_LOAD_WAVE_STEP_MS; } // ── Main component ───────────────────────────────────────────────────── diff --git a/frontend/components/dashboard/scan-terminal/__tests__/refreshCadencePolicy.test.ts b/frontend/components/dashboard/scan-terminal/__tests__/refreshCadencePolicy.test.ts index 5ee16fbd..ae49c4dd 100644 --- a/frontend/components/dashboard/scan-terminal/__tests__/refreshCadencePolicy.test.ts +++ b/frontend/components/dashboard/scan-terminal/__tests__/refreshCadencePolicy.test.ts @@ -174,6 +174,18 @@ export async function runTests() { __getInitialDetailLoadDelayMsForTest({ compact: true, isActive: false, isMaximized: false, slotIndex: 3 }) > 0, "later non-active grid charts should defer full-detail loading after first paint", ); + assert( + __getInitialDetailLoadDelayMsForTest({ compact: true, isActive: false, isMaximized: false, slotIndex: 3 }) === + __getInitialDetailLoadDelayMsForTest({ compact: true, isActive: false, isMaximized: false, slotIndex: 5 }), + "deferred grid charts should load in same-wave groups so detail-batch can coalesce them", + ); + assert( + __getInitialDetailLoadDelayMsForTest({ compact: true, isActive: false, isMaximized: false, slotIndex: 6 }) === + __getInitialDetailLoadDelayMsForTest({ compact: true, isActive: false, isMaximized: false, slotIndex: 8 }) && + __getInitialDetailLoadDelayMsForTest({ compact: true, isActive: false, isMaximized: false, slotIndex: 6 }) > + __getInitialDetailLoadDelayMsForTest({ compact: true, isActive: false, isMaximized: false, slotIndex: 5 }), + "later deferred grid charts should form a second batch wave instead of one request per slot", + ); assert( __getInitialDetailLoadDelayMsForTest({ compact: true, isActive: true, isMaximized: false, slotIndex: 8 }) === 0 && __getInitialDetailLoadDelayMsForTest({ compact: true, isActive: false, isMaximized: true, slotIndex: 8 }) === 0,