feat: 优化接口速度

This commit is contained in:
2026-04-24 22:02:53 +08:00
parent fd20a4411b
commit d1c5b818d9
5 changed files with 148 additions and 60 deletions
@@ -12,6 +12,30 @@ import { ScreenRecord, TimeDistributionPoint, Segment, Marker } from '../types';
import { formatMemory, formatDate } from '../utils';
import { useStarToggle } from '../hooks/useStarToggle';
const inFlightJsonRequests = new Map<string, Promise<unknown>>();
const fetchJsonOnce = async <T,>(url: string): Promise<T> => {
const existingRequest = inFlightJsonRequests.get(url);
if (existingRequest) {
return existingRequest as Promise<T>;
}
const request = fetch(url, { cache: 'no-store' })
.then(async (response) => {
if (!response.ok) {
throw new Error(`Request failed with status ${response.status}`);
}
return response.json() as Promise<T>;
})
.finally(() => {
inFlightJsonRequests.delete(url);
});
inFlightJsonRequests.set(url, request);
return request as Promise<T>;
};
interface ScreenshotsTabProps {
hostname: string;
selectedDate: string | null;
@@ -27,6 +51,9 @@ export default function ScreenshotsTab({
jumpRequest,
onLastUpdateChange
}: ScreenshotsTabProps) {
const timeDistributionRequestIdRef = useRef(0);
const hourlyRecordsRequestIdRef = useRef(0);
// 状态管理
const [timeDistribution, setTimeDistribution] = useState<TimeDistributionPoint[]>([]);
const [records, setRecords] = useState<ScreenRecord[]>([]);
@@ -58,30 +85,50 @@ export default function ScreenshotsTab({
// 获取时间分布数据
const fetchTimeDistribution = async () => {
const requestId = ++timeDistributionRequestIdRef.current;
try {
setLoadingDistribution(true);
const response = await fetch(`/hosts/${hostname}/time-distribution`);
if (!response.ok) throw new Error('获取时间分布数据失败');
const data = await response.json();
const data = await fetchJsonOnce<{ distribution: TimeDistributionPoint[] }>(
`/hosts/${hostname}/time-distribution`
);
if (requestId !== timeDistributionRequestIdRef.current) {
return;
}
setTimeDistribution(data.distribution);
} catch (error) {
console.error('获取时间分布数据失败:', error);
if (requestId === timeDistributionRequestIdRef.current) {
console.error('获取时间分布数据失败:', error);
}
} finally {
setLoadingDistribution(false);
if (requestId === timeDistributionRequestIdRef.current) {
setLoadingDistribution(false);
}
}
};
// 获取小时记录
const fetchHourlyRecords = async (startTime: number, endTime: number, options?: { targetRecordId?: string, keepSelection?: boolean }) => {
const requestId = ++hourlyRecordsRequestIdRef.current;
const requestUrl = `/hosts/${hostname}/screenshots?startTime=${startTime}&endTime=${endTime}`;
try {
setLoadingRecords(true);
setShowDetailTimeline(true);
const response = await fetch(
`/hosts/${hostname}/screenshots?startTime=${startTime}&endTime=${endTime}`
);
if (!response.ok) throw new Error('获取记录数据失败');
const data = await response.json();
const newRecords = data.records.reverse();
const data = await fetchJsonOnce<{
lastUpdate: string | null;
records: ScreenRecord[];
}>(requestUrl);
if (requestId !== hourlyRecordsRequestIdRef.current) {
return;
}
const newRecords = data.records;
setRecords(newRecords);
onLastUpdateChange(data.lastUpdate);
setTimeRange({ min: startTime * 1000, max: endTime * 1000 });
@@ -104,9 +151,13 @@ export default function ScreenshotsTab({
}
});
} catch (error) {
console.error('获取记录数据失败:', error);
if (requestId === hourlyRecordsRequestIdRef.current) {
console.error('获取记录数据失败:', error);
}
} finally {
setLoadingRecords(false);
if (requestId === hourlyRecordsRequestIdRef.current) {
setLoadingRecords(false);
}
}
};