perf: optimize all home page components

This commit is contained in:
wonfen
2025-03-17 11:47:02 +08:00
parent 6239f81f36
commit 105de99d06
13 changed files with 1612 additions and 1726 deletions

View File

@@ -7,47 +7,94 @@ import { EnhancedCard } from "./enhanced-card";
import useSWR from "swr";
import { getRules } from "@/services/api";
import { getAppUptime } from "@/services/cmds";
import { useState } from "react";
import { useMemo } from "react";
// 将毫秒转换为时:分:秒格式的函数
const formatUptime = (uptimeMs: number) => {
const hours = Math.floor(uptimeMs / 3600000);
const minutes = Math.floor((uptimeMs % 3600000) / 60000);
const seconds = Math.floor((uptimeMs % 60000) / 1000);
return `${hours}:${minutes.toString().padStart(2, "0")}:${seconds.toString().padStart(2, "0")}`;
};
export const ClashInfoCard = () => {
const { t } = useTranslation();
const { clashInfo } = useClashInfo();
const { version: clashVersion } = useClash();
// 计算运行时间
const [uptime, setUptime] = useState("0:00:00");
// 使用SWR定期获取应用运行时间
useSWR(
// 使用SWR获取应用运行时间降低更新频率
const { data: uptimeMs = 0 } = useSWR(
"appUptime",
async () => {
const uptimeMs = await getAppUptime();
// 将毫秒转换为时:分:秒格式
const hours = Math.floor(uptimeMs / 3600000);
const minutes = Math.floor((uptimeMs % 3600000) / 60000);
const seconds = Math.floor((uptimeMs % 60000) / 1000);
setUptime(
`${hours}:${minutes.toString().padStart(2, "0")}:${seconds.toString().padStart(2, "0")}`,
);
return uptimeMs;
},
getAppUptime,
{
refreshInterval: 1000, // 每秒更新一次
refreshInterval: 1000,
revalidateOnFocus: false,
dedupingInterval: 500,
dedupingInterval: 1000,
},
);
// 获取规则数
const { data: rulesData } = useSWR("getRules", getRules, {
fallbackData: [],
suspense: false,
// 使用useMemo缓存格式化后的uptime避免频繁计算
const uptime = useMemo(() => formatUptime(uptimeMs), [uptimeMs]);
// 获取规则数据,只在组件加载时获取一次
const { data: rules = [] } = useSWR("getRules", getRules, {
revalidateOnFocus: false,
errorRetryCount: 2,
});
// 获取规则数据
const rules = rulesData || [];
// 使用备忘录组件内容,减少重新渲染
const cardContent = useMemo(() => {
if (!clashInfo) return null;
return (
<Stack spacing={1.5}>
<Stack direction="row" justifyContent="space-between">
<Typography variant="body2" color="text.secondary">
{t("Core Version")}
</Typography>
<Typography variant="body2" fontWeight="medium">
{clashVersion || "-"}
</Typography>
</Stack>
<Divider />
<Stack direction="row" justifyContent="space-between">
<Typography variant="body2" color="text.secondary">
{t("System Proxy Address")}
</Typography>
<Typography variant="body2" fontWeight="medium">
{clashInfo.server || "-"}
</Typography>
</Stack>
<Divider />
<Stack direction="row" justifyContent="space-between">
<Typography variant="body2" color="text.secondary">
{t("Mixed Port")}
</Typography>
<Typography variant="body2" fontWeight="medium">
{clashInfo.mixed_port || "-"}
</Typography>
</Stack>
<Divider />
<Stack direction="row" justifyContent="space-between">
<Typography variant="body2" color="text.secondary">
{t("Uptime")}
</Typography>
<Typography variant="body2" fontWeight="medium">
{uptime}
</Typography>
</Stack>
<Divider />
<Stack direction="row" justifyContent="space-between">
<Typography variant="body2" color="text.secondary">
{t("Rules Count")}
</Typography>
<Typography variant="body2" fontWeight="medium">
{rules.length}
</Typography>
</Stack>
</Stack>
);
}, [clashInfo, clashVersion, t, uptime, rules.length]);
return (
<EnhancedCard
@@ -56,54 +103,7 @@ export const ClashInfoCard = () => {
iconColor="warning"
action={null}
>
{clashInfo && (
<Stack spacing={1.5}>
<Stack direction="row" justifyContent="space-between">
<Typography variant="body2" color="text.secondary">
{t("Core Version")}
</Typography>
<Typography variant="body2" fontWeight="medium">
{clashVersion || "-"}
</Typography>
</Stack>
<Divider />
<Stack direction="row" justifyContent="space-between">
<Typography variant="body2" color="text.secondary">
{t("System Proxy Address")}
</Typography>
<Typography variant="body2" fontWeight="medium">
{clashInfo.server || "-"}
</Typography>
</Stack>
<Divider />
<Stack direction="row" justifyContent="space-between">
<Typography variant="body2" color="text.secondary">
{t("Mixed Port")}
</Typography>
<Typography variant="body2" fontWeight="medium">
{clashInfo.mixed_port || "-"}
</Typography>
</Stack>
<Divider />
<Stack direction="row" justifyContent="space-between">
<Typography variant="body2" color="text.secondary">
{t("Uptime")}
</Typography>
<Typography variant="body2" fontWeight="medium">
{uptime}
</Typography>
</Stack>
<Divider />
<Stack direction="row" justifyContent="space-between">
<Typography variant="body2" color="text.secondary">
{t("Rules Count")}
</Typography>
<Typography variant="body2" fontWeight="medium">
{rules.length}
</Typography>
</Stack>
</Stack>
)}
{cardContent}
</EnhancedCard>
);
};