- 新建 RefreshCountdown 组件,内部持有 timer,消除 App 每秒重渲染 - TargetBoard 分组逻辑 useMemo 化,避免 targets 引用不变时重复计算 - TargetGroup 加 React.memo,阻断无效渲染 - TrendChart 加 React.memo + chartData useMemo,避免 recharts 不必要重绘 - OverviewTab 统计项去掉 Card 包裹,改用纯 CSS 实现视觉效果 - 同步更新 refresh-control 和 target-detail-drawer spec 性能提升:消除每秒全组件树重渲染,减少 DOM 节点数
53 lines
1.5 KiB
TypeScript
53 lines
1.5 KiB
TypeScript
import type { PrimaryTableCol } from "tdesign-react";
|
|
|
|
import { memo } from "react";
|
|
import { Card, PrimaryTable, Space, Tag } from "tdesign-react";
|
|
|
|
import type { TargetStatus } from "../../shared/api";
|
|
|
|
interface TargetGroupProps {
|
|
columns: Array<PrimaryTableCol<TargetStatus>>;
|
|
name: string;
|
|
onTargetClick: (target: TargetStatus) => void;
|
|
targets: TargetStatus[];
|
|
}
|
|
|
|
export const TargetGroup = memo(function TargetGroup({ columns, name, onTargetClick, targets }: TargetGroupProps) {
|
|
const up = targets.filter((t) => t.latestCheck?.matched).length;
|
|
const down = targets.length - up;
|
|
const displayName = name === "default" ? "默认分组" : name;
|
|
|
|
return (
|
|
<Card
|
|
actions={
|
|
<Space size={8}>
|
|
<Tag theme="success" title="正常" variant="light">
|
|
{up}
|
|
</Tag>
|
|
<Tag theme="danger" title="异常" variant="light">
|
|
{down}
|
|
</Tag>
|
|
</Space>
|
|
}
|
|
headerBordered
|
|
title={displayName}
|
|
>
|
|
<PrimaryTable
|
|
className="clickable-table"
|
|
columns={columns}
|
|
data={targets}
|
|
defaultSort={[{ descending: true, sortBy: "latestCheck.matched" }]}
|
|
hover
|
|
onRowClick={({ row }) => onTargetClick(row)}
|
|
rowClassName={({ row }) => {
|
|
const target = row;
|
|
return target.latestCheck?.matched === false ? "row-down" : "";
|
|
}}
|
|
rowKey="id"
|
|
size="small"
|
|
stripe
|
|
/>
|
|
</Card>
|
|
);
|
|
});
|