perf(web): pause hidden live polling
This commit is contained in:
@@ -6,7 +6,7 @@ import { api } from '../../api/client';
|
||||
import type { HistoryDataResponse, HistoryDataRow, HistoryExportRequest, HistoryMetricDefinition, HistorySeriesResponse } from '../../api/types';
|
||||
import { buildHistorySeriesPanels, formatExportFileSize, formatHistoryValue, formatSeriesGrain, historyExportPollInterval, parseHistoryKeywords } from '../domain/history';
|
||||
import { InlineError } from '../shared/AsyncState';
|
||||
import { QUERY_MEMORY, retainPreviousPageWithinScope } from '../queryPolicy';
|
||||
import { LIVE_QUERY_POLICY, QUERY_MEMORY, retainPreviousPageWithinScope } from '../queryPolicy';
|
||||
import { usePlatformSession } from '../auth/AuthGate';
|
||||
import { canOperate } from '../auth/session';
|
||||
|
||||
@@ -50,7 +50,7 @@ function ExportJobsPanel() {
|
||||
queryKey: ['history-exports'],
|
||||
queryFn: ({ signal }) => api.historyExports(signal),
|
||||
refetchInterval: (current) => historyExportPollInterval(current.state.data),
|
||||
refetchIntervalInBackground: false,
|
||||
...LIVE_QUERY_POLICY,
|
||||
gcTime: QUERY_MEMORY.highVolumeGcTime
|
||||
});
|
||||
const jobs = query.data ?? [];
|
||||
|
||||
@@ -8,7 +8,7 @@ import { FleetMap } from '../map/FleetMap';
|
||||
import { EmptyState, InlineError } from '../shared/AsyncState';
|
||||
import { formatNumber, relativeFreshness, statusLabel, vehicleStatus } from '../domain/monitor';
|
||||
import { MAX_MONITOR_SEARCH_TERMS, MONITOR_REFRESH, monitorFilterScope, monitorQueryParams, parseMonitorSearchTerms, useMonitorData, useMonitorVehicleCard, type MonitorViewport } from '../hooks/useMonitorData';
|
||||
import { QUERY_MEMORY, retainPreviousPageWithinScope } from '../queryPolicy';
|
||||
import { LIVE_QUERY_POLICY, QUERY_MEMORY, retainPreviousPageWithinScope } from '../queryPolicy';
|
||||
|
||||
const protocols = ['', 'GB32960', 'JT808', 'YUTONG_MQTT'];
|
||||
const statuses = ['', 'online', 'offline', 'driving', 'idle'];
|
||||
@@ -251,7 +251,8 @@ export default function MonitorPage() {
|
||||
queryKey: ['monitor', 'vehicle-list', listScope, listLimit, listOffset],
|
||||
queryFn: ({ signal }) => api.vehicleRealtime(listParams, signal),
|
||||
enabled: mode === 'list', placeholderData: retainPreviousPageWithinScope<Page<VehicleRealtimeRow>>(listScope, 2), refetchInterval: mode === 'list' ? MONITOR_REFRESH.fleet : false,
|
||||
gcTime: QUERY_MEMORY.highVolumeGcTime
|
||||
gcTime: QUERY_MEMORY.highVolumeGcTime,
|
||||
...LIVE_QUERY_POLICY
|
||||
});
|
||||
const rows = useMemo(() => {
|
||||
const data = vehicles.data?.items ?? [];
|
||||
|
||||
@@ -22,6 +22,12 @@ test('reconciles service identities with bound and identity-required vehicles',
|
||||
render(<QueryClientProvider client={client}><OperationsPage /></QueryClientProvider>);
|
||||
|
||||
expect(await screen.findByText('1035 / 234')).toBeInTheDocument();
|
||||
for (const key of [['ops-health-v2'], ['ops-source-readiness-v2']]) {
|
||||
const query = client.getQueryCache().find({ queryKey: key });
|
||||
const liveOptions = query?.options as { refetchIntervalInBackground?: boolean; refetchOnWindowFocus?: boolean };
|
||||
expect(liveOptions.refetchIntervalInBackground).toBe(false);
|
||||
expect(liveOptions.refetchOnWindowFocus).toBe(true);
|
||||
}
|
||||
expect(screen.getByText('服务身份 / 在线')).toBeInTheDocument();
|
||||
expect(screen.getByText('已绑定 1024 · 待绑定 11')).toBeInTheDocument();
|
||||
expect(screen.queryByText('统一车辆视角')).not.toBeInTheDocument();
|
||||
|
||||
@@ -2,14 +2,15 @@ import { IconRefresh } from '@douyinfe/semi-icons';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { api } from '../../api/client';
|
||||
import { InlineError } from '../shared/AsyncState';
|
||||
import { LIVE_QUERY_POLICY, QUERY_MEMORY } from '../queryPolicy';
|
||||
|
||||
function statusLabel(status: string) {
|
||||
return { ok: '正常', warning: '关注', error: '异常' }[status] ?? status;
|
||||
}
|
||||
|
||||
export default function OperationsPage() {
|
||||
const health = useQuery({ queryKey: ['ops-health-v2'], queryFn: ({ signal }) => api.opsHealth(signal), refetchInterval: 15_000, staleTime: 8_000 });
|
||||
const readiness = useQuery({ queryKey: ['ops-source-readiness-v2'], queryFn: ({ signal }) => api.sourceReadiness(signal), refetchInterval: 30_000, staleTime: 15_000 });
|
||||
const health = useQuery({ queryKey: ['ops-health-v2'], queryFn: ({ signal }) => api.opsHealth(signal), refetchInterval: 15_000, staleTime: 8_000, gcTime: QUERY_MEMORY.summaryGcTime, ...LIVE_QUERY_POLICY });
|
||||
const readiness = useQuery({ queryKey: ['ops-source-readiness-v2'], queryFn: ({ signal }) => api.sourceReadiness(signal), refetchInterval: 30_000, staleTime: 15_000, gcTime: QUERY_MEMORY.summaryGcTime, ...LIVE_QUERY_POLICY });
|
||||
const data = health.data; const sources = readiness.data;
|
||||
const refresh = () => Promise.all([health.refetch(), readiness.refetch()]);
|
||||
return <div className="v2-ops-page">
|
||||
|
||||
@@ -9,7 +9,7 @@ import { api } from '../../api/client';
|
||||
import type { LatestTelemetryResponse, QualityIssueRow, VehicleDetail, VehicleProfileSyncItem, VehicleProfileSyncResult } from '../../api/types';
|
||||
import { usePlatformSession } from '../auth/AuthGate';
|
||||
import { canAdminister } from '../auth/session';
|
||||
import { QUERY_MEMORY } from '../queryPolicy';
|
||||
import { LIVE_QUERY_POLICY, QUERY_MEMORY } from '../queryPolicy';
|
||||
import { formatTelemetryTime, formatTelemetryValue, telemetryQualityLabel } from '../domain/telemetry';
|
||||
import { formatZhNumber } from '../domain/formatters';
|
||||
import { parseVehicleProfileSyncCSV, vehicleProfileSyncCSVHeader } from '../domain/profileSync';
|
||||
@@ -198,7 +198,7 @@ function VehicleRecord({ detail, telemetry, telemetryPending, telemetryError, on
|
||||
export default function VehiclePage() {
|
||||
const { vin } = useParams();
|
||||
const query = useQuery({ queryKey: ['vehicle-detail', vin], enabled: Boolean(vin), queryFn: ({ signal }) => api.vehicleDetail(new URLSearchParams({ keyword: vin!, limit: '20' }), signal), gcTime: QUERY_MEMORY.summaryGcTime });
|
||||
const telemetry = useQuery({ queryKey: ['vehicle-latest-telemetry', vin], enabled: Boolean(vin), queryFn: ({ signal }) => api.latestTelemetry(vin!, signal), staleTime: 10_000, gcTime: QUERY_MEMORY.summaryGcTime, refetchInterval: 20_000, refetchIntervalInBackground: false });
|
||||
const telemetry = useQuery({ queryKey: ['vehicle-latest-telemetry', vin], enabled: Boolean(vin), queryFn: ({ signal }) => api.latestTelemetry(vin!, signal), staleTime: 10_000, gcTime: QUERY_MEMORY.summaryGcTime, refetchInterval: 20_000, ...LIVE_QUERY_POLICY });
|
||||
if (!vin) return <VehicleSearch />;
|
||||
if (query.isPending) return <PageLoading />;
|
||||
if (query.isError) return <div className="v2-page-error"><InlineError message={query.error instanceof Error ? query.error.message : '车辆档案加载失败'} onRetry={() => query.refetch()} /></div>;
|
||||
|
||||
Reference in New Issue
Block a user