优化日内温度曲线图加载性能并修复图标旋转动画
- AiCityTemperatureChart:React.memo 包裹 + useMemo 依赖移除 detail 避免每帧重算 - ScanTerminalCard 等 9 个 CSS Module:animation: spin 改为 :global(spin) 修复 CSS Modules 作用域问题
This commit is contained in:
@@ -358,7 +358,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.spin {
|
.spin {
|
||||||
animation: spin 0.9s linear infinite;
|
animation: :global(spin) 0.9s linear infinite;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 960px) {
|
@media (max-width: 960px) {
|
||||||
|
|||||||
@@ -544,7 +544,7 @@
|
|||||||
border: 2px solid rgba(34, 211, 238, 0.1);
|
border: 2px solid rgba(34, 211, 238, 0.1);
|
||||||
border-top-color: var(--accent-cyan);
|
border-top-color: var(--accent-cyan);
|
||||||
border-radius: 50%;
|
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);
|
box-shadow: 0 0 15px rgba(34, 211, 238, 0.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -86,7 +86,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.root :global(.future-refresh-btn.spinning svg) {
|
.root :global(.future-refresh-btn.spinning svg) {
|
||||||
animation: spin 1s linear infinite;
|
animation: :global(spin) 1s linear infinite;
|
||||||
color: var(--accent-cyan);
|
color: var(--accent-cyan);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -209,7 +209,7 @@
|
|||||||
color: var(--accent-cyan);
|
color: var(--accent-cyan);
|
||||||
}
|
}
|
||||||
.root :global(.refresh-btn.spinning) {
|
.root :global(.refresh-btn.spinning) {
|
||||||
animation: spin 1s linear infinite;
|
animation: :global(spin) 1s linear infinite;
|
||||||
}
|
}
|
||||||
|
|
||||||
.root :global(.locale-switch) {
|
.root :global(.locale-switch) {
|
||||||
|
|||||||
@@ -111,7 +111,7 @@
|
|||||||
border-radius: 999px;
|
border-radius: 999px;
|
||||||
border: 2px solid rgba(34, 211, 238, 0.22);
|
border: 2px solid rgba(34, 211, 238, 0.22);
|
||||||
border-top-color: rgba(34, 211, 238, 0.92);
|
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) {
|
.root :global(.panel-meta) {
|
||||||
|
|||||||
@@ -56,7 +56,7 @@
|
|||||||
border: 2px solid rgba(34, 211, 238, 0.18);
|
border: 2px solid rgba(34, 211, 238, 0.18);
|
||||||
border-top-color: #22d3ee;
|
border-top-color: #22d3ee;
|
||||||
border-radius: 999px;
|
border-radius: 999px;
|
||||||
animation: spin 0.8s linear infinite;
|
animation: :global(spin) 0.8s linear infinite;
|
||||||
}
|
}
|
||||||
|
|
||||||
.root :global(.future-v2-sync-strip) {
|
.root :global(.future-v2-sync-strip) {
|
||||||
|
|||||||
@@ -648,7 +648,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.root :global(.scan-ai-city-icon-button .spin) {
|
.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) {
|
.root :global(.scan-ai-city-collapse) {
|
||||||
|
|||||||
@@ -95,7 +95,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.root :global(.scan-status-chip .spin) {
|
.root :global(.scan-status-chip .spin) {
|
||||||
animation: spin 1s linear infinite;
|
animation: :global(spin) 1s linear infinite;
|
||||||
}
|
}
|
||||||
|
|
||||||
.root :global(.scan-table-shell) {
|
.root :global(.scan-table-shell) {
|
||||||
|
|||||||
@@ -280,5 +280,5 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.root :global(.scan-ghost-button .spin) {
|
.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 type { ChartConfiguration } from "chart.js";
|
||||||
import { useMemo, useRef } from "react";
|
import { memo, useMemo, useRef } from "react";
|
||||||
import { BarChart3 } from "lucide-react";
|
import { BarChart3 } from "lucide-react";
|
||||||
import type { CityDetail } from "@/lib/dashboard-types";
|
import type { CityDetail } from "@/lib/dashboard-types";
|
||||||
import { useChart } from "@/hooks/useChart";
|
import { useChart } from "@/hooks/useChart";
|
||||||
@@ -61,7 +61,7 @@ function buildTemperatureChartSignature(detail: CityDetail) {
|
|||||||
].join("::");
|
].join("::");
|
||||||
}
|
}
|
||||||
|
|
||||||
export function AiCityTemperatureChart({ detail }: { detail: CityDetail }) {
|
export const AiCityTemperatureChart = memo(function AiCityTemperatureChart({ detail }: { detail: CityDetail }) {
|
||||||
const { locale } = useI18n();
|
const { locale } = useI18n();
|
||||||
const sectionRef = useRef<HTMLElement | null>(null);
|
const sectionRef = useRef<HTMLElement | null>(null);
|
||||||
const cityKey = `${detail.name || detail.display_name || ""}:${detail.local_date || ""}`;
|
const cityKey = `${detail.name || detail.display_name || ""}:${detail.local_date || ""}`;
|
||||||
@@ -71,7 +71,8 @@ export function AiCityTemperatureChart({ detail }: { detail: CityDetail }) {
|
|||||||
);
|
);
|
||||||
const computedChartData = useMemo(
|
const computedChartData = useMemo(
|
||||||
() => getTemperatureChartData(detail, locale),
|
() => getTemperatureChartData(detail, locale),
|
||||||
[chartSignature, detail, locale],
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
[chartSignature, locale],
|
||||||
);
|
);
|
||||||
const lastChartDataRef = useRef<{
|
const lastChartDataRef = useRef<{
|
||||||
cityKey: string;
|
cityKey: string;
|
||||||
@@ -235,5 +236,5 @@ export function AiCityTemperatureChart({ detail }: { detail: CityDetail }) {
|
|||||||
) : null}
|
) : null}
|
||||||
</section>
|
</section>
|
||||||
);
|
);
|
||||||
}
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user