feat: 优化接口速度
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user