优化日内温度曲线图加载性能并修复图标旋转动画

- AiCityTemperatureChart:React.memo 包裹 + useMemo 依赖移除 detail 避免每帧重算
- ScanTerminalCard 等 9 个 CSS Module:animation: spin 改为 :global(spin) 修复 CSS Modules 作用域问题
This commit is contained in:
2569718930@qq.com
2026-05-14 17:31:25 +08:00
parent 8dd9aa59b3
commit 4f13faa311
10 changed files with 14 additions and 13 deletions
@@ -358,7 +358,7 @@
}
.spin {
animation: spin 0.9s linear infinite;
animation: :global(spin) 0.9s linear infinite;
}
@media (max-width: 960px) {
@@ -544,7 +544,7 @@
border: 2px solid rgba(34, 211, 238, 0.1);
border-top-color: var(--accent-cyan);
border-radius: 50%;
animation: spin 0.8s cubic-bezier(0.4, 0, 0.2, 1) infinite;
animation: :global(spin) 0.8s cubic-bezier(0.4, 0, 0.2, 1) infinite;
box-shadow: 0 0 15px rgba(34, 211, 238, 0.1);
}
@@ -86,7 +86,7 @@
}
.root :global(.future-refresh-btn.spinning svg) {
animation: spin 1s linear infinite;
animation: :global(spin) 1s linear infinite;
color: var(--accent-cyan);
}
@@ -209,7 +209,7 @@
color: var(--accent-cyan);
}
.root :global(.refresh-btn.spinning) {
animation: spin 1s linear infinite;
animation: :global(spin) 1s linear infinite;
}
.root :global(.locale-switch) {
@@ -111,7 +111,7 @@
border-radius: 999px;
border: 2px solid rgba(34, 211, 238, 0.22);
border-top-color: rgba(34, 211, 238, 0.92);
animation: spin 0.8s linear infinite;
animation: :global(spin) 0.8s linear infinite;
}
.root :global(.panel-meta) {
@@ -56,7 +56,7 @@
border: 2px solid rgba(34, 211, 238, 0.18);
border-top-color: #22d3ee;
border-radius: 999px;
animation: spin 0.8s linear infinite;
animation: :global(spin) 0.8s linear infinite;
}
.root :global(.future-v2-sync-strip) {
@@ -648,7 +648,7 @@
}
.root :global(.scan-ai-city-icon-button .spin) {
animation: spin 1s linear infinite;
animation: :global(spin) 1s linear infinite;
}
.root :global(.scan-ai-city-collapse) {
@@ -95,7 +95,7 @@
}
.root :global(.scan-status-chip .spin) {
animation: spin 1s linear infinite;
animation: :global(spin) 1s linear infinite;
}
.root :global(.scan-table-shell) {
@@ -280,5 +280,5 @@
}
.root :global(.scan-ghost-button .spin) {
animation: spin 1s linear infinite;
animation: :global(spin) 1s linear infinite;
}
@@ -1,5 +1,5 @@
import type { ChartConfiguration } from "chart.js";
import { useMemo, useRef } from "react";
import { memo, useMemo, useRef } from "react";
import { BarChart3 } from "lucide-react";
import type { CityDetail } from "@/lib/dashboard-types";
import { useChart } from "@/hooks/useChart";
@@ -61,7 +61,7 @@ function buildTemperatureChartSignature(detail: CityDetail) {
].join("::");
}
export function AiCityTemperatureChart({ detail }: { detail: CityDetail }) {
export const AiCityTemperatureChart = memo(function AiCityTemperatureChart({ detail }: { detail: CityDetail }) {
const { locale } = useI18n();
const sectionRef = useRef<HTMLElement | null>(null);
const cityKey = `${detail.name || detail.display_name || ""}:${detail.local_date || ""}`;
@@ -71,7 +71,8 @@ export function AiCityTemperatureChart({ detail }: { detail: CityDetail }) {
);
const computedChartData = useMemo(
() => getTemperatureChartData(detail, locale),
[chartSignature, detail, locale],
// eslint-disable-next-line react-hooks/exhaustive-deps
[chartSignature, locale],
);
const lastChartDataRef = useRef<{
cityKey: string;
@@ -235,5 +236,5 @@ export function AiCityTemperatureChart({ detail }: { detail: CityDetail }) {
) : null}
</section>
);
}
});