缓存TTL 2min→10min,空闲时预加载相邻区域数据
This commit is contained in:
@@ -8,10 +8,11 @@ import {
|
|||||||
shouldSkipManualTerminalRefresh,
|
shouldSkipManualTerminalRefresh,
|
||||||
} from "@/components/dashboard/scan-terminal/scan-terminal-client";
|
} from "@/components/dashboard/scan-terminal/scan-terminal-client";
|
||||||
import { useRemoteDataQuery } from "@/components/dashboard/scan-terminal/use-remote-data-query";
|
import { useRemoteDataQuery } from "@/components/dashboard/scan-terminal/use-remote-data-query";
|
||||||
|
import { REGIONS } from "@/components/dashboard/scan-terminal/continent-grouping";
|
||||||
import type { ScanTerminalResponse } from "@/lib/dashboard-types";
|
import type { ScanTerminalResponse } from "@/lib/dashboard-types";
|
||||||
|
|
||||||
const SCAN_CACHE_PREFIX = "polyweather_scan_v2";
|
const SCAN_CACHE_PREFIX = "polyweather_scan_v2";
|
||||||
const SCAN_CACHE_TTL_MS = 2 * 60 * 1000; // 2 min — cities list instant on revisit
|
const SCAN_CACHE_TTL_MS = 10 * 60 * 1000; // 10 min — cities list instant on revisit
|
||||||
|
|
||||||
function scanCacheKey(tradingRegion: string): string {
|
function scanCacheKey(tradingRegion: string): string {
|
||||||
return `${SCAN_CACHE_PREFIX}:${tradingRegion || "all"}`;
|
return `${SCAN_CACHE_PREFIX}:${tradingRegion || "all"}`;
|
||||||
@@ -136,6 +137,37 @@ export function useScanTerminalQuery({
|
|||||||
return () => window.clearInterval(intervalId);
|
return () => window.clearInterval(intervalId);
|
||||||
}, [fetchScanTerminal, isLoading, isPro, proAccessLoading]);
|
}, [fetchScanTerminal, isLoading, isPro, proAccessLoading]);
|
||||||
|
|
||||||
|
// Preload adjacent regions in idle time for instant tab switches
|
||||||
|
useEffect(() => {
|
||||||
|
if (typeof window === "undefined" || !tradingRegion || !isPro) return;
|
||||||
|
const sorted = [...REGIONS].sort((a, b) => a.sort - b.sort);
|
||||||
|
const idx = sorted.findIndex((r) => r.key === tradingRegion);
|
||||||
|
if (idx < 0) return;
|
||||||
|
const neighbors = [idx - 1, idx + 1]
|
||||||
|
.filter((i) => i >= 0 && i < sorted.length)
|
||||||
|
.map((i) => sorted[i].key);
|
||||||
|
if (!neighbors.length) return;
|
||||||
|
|
||||||
|
const preloadOne = (region: string) => {
|
||||||
|
if (readScanCache(region)) return; // already cached
|
||||||
|
const idleFn = (window as any).requestIdleCallback || ((cb: () => void) => setTimeout(cb, 5000));
|
||||||
|
const handle = idleFn(() => {
|
||||||
|
void scanTerminalClient.getTerminal({
|
||||||
|
forceRefresh: false,
|
||||||
|
signal: new AbortController().signal,
|
||||||
|
tradingRegion: region,
|
||||||
|
}).then((data) => { writeScanCache(data, region); });
|
||||||
|
});
|
||||||
|
return handle;
|
||||||
|
};
|
||||||
|
|
||||||
|
const handles = neighbors.map(preloadOne).filter(Boolean);
|
||||||
|
return () => {
|
||||||
|
const cancelFn = (window as any).cancelIdleCallback || clearTimeout;
|
||||||
|
handles.forEach((h) => { try { cancelFn(h); } catch { /* */ } });
|
||||||
|
};
|
||||||
|
}, [tradingRegion, isPro]);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
refreshScanTerminalManually,
|
refreshScanTerminalManually,
|
||||||
scanError,
|
scanError,
|
||||||
|
|||||||
Reference in New Issue
Block a user