feat: 优化首页性能
This commit is contained in:
40
app/components/RefreshButton.jsx
Normal file
40
app/components/RefreshButton.jsx
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import { RefreshIcon } from './Icons';
|
||||||
|
|
||||||
|
export default function RefreshButton({ refreshCycleStartRef, refreshMs, manualRefresh, refreshing, fundsLength }) {
|
||||||
|
|
||||||
|
// 刷新周期进度 0~1,用于环形进度条
|
||||||
|
const [refreshProgress, setRefreshProgress] = useState(0);
|
||||||
|
|
||||||
|
// 刷新进度条:每 100ms 更新一次进度
|
||||||
|
useEffect(() => {
|
||||||
|
if (fundsLength === 0 || refreshMs <= 0) return;
|
||||||
|
const t = setInterval(() => {
|
||||||
|
const elapsed = Date.now() - refreshCycleStartRef.current;
|
||||||
|
const p = Math.min(1, elapsed / refreshMs);
|
||||||
|
setRefreshProgress(p);
|
||||||
|
}, 100);
|
||||||
|
return () => clearInterval(t);
|
||||||
|
}, [fundsLength, refreshMs]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className="refresh-btn-wrap"
|
||||||
|
style={{ '--progress': refreshProgress }}
|
||||||
|
title={`刷新周期 ${Math.round(refreshMs / 1000)} 秒`}
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
className="icon-button"
|
||||||
|
aria-label="立即刷新"
|
||||||
|
onClick={manualRefresh}
|
||||||
|
disabled={refreshing || fundsLength === 0}
|
||||||
|
aria-busy={refreshing}
|
||||||
|
title="立即刷新"
|
||||||
|
>
|
||||||
|
<RefreshIcon className={refreshing ? 'spin' : ''} width="18" height="18" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
39
app/page.jsx
39
app/page.jsx
@@ -36,6 +36,7 @@ import TradeModal from "./components/TradeModal";
|
|||||||
import TransactionHistoryModal from "./components/TransactionHistoryModal";
|
import TransactionHistoryModal from "./components/TransactionHistoryModal";
|
||||||
import AddHistoryModal from "./components/AddHistoryModal";
|
import AddHistoryModal from "./components/AddHistoryModal";
|
||||||
import UpdatePromptModal from "./components/UpdatePromptModal";
|
import UpdatePromptModal from "./components/UpdatePromptModal";
|
||||||
|
import RefreshButton from "./components/RefreshButton";
|
||||||
import WeChatModal from "./components/WeChatModal";
|
import WeChatModal from "./components/WeChatModal";
|
||||||
import DcaModal from "./components/DcaModal";
|
import DcaModal from "./components/DcaModal";
|
||||||
import githubImg from "./assets/github.svg";
|
import githubImg from "./assets/github.svg";
|
||||||
@@ -311,8 +312,6 @@ export default function HomePage() {
|
|||||||
|
|
||||||
// 全局刷新状态
|
// 全局刷新状态
|
||||||
const [refreshing, setRefreshing] = useState(false);
|
const [refreshing, setRefreshing] = useState(false);
|
||||||
// 刷新周期进度 0~1,用于环形进度条
|
|
||||||
const [refreshProgress, setRefreshProgress] = useState(0);
|
|
||||||
|
|
||||||
// 收起/展开状态
|
// 收起/展开状态
|
||||||
const [collapsedCodes, setCollapsedCodes] = useState(new Set());
|
const [collapsedCodes, setCollapsedCodes] = useState(new Set());
|
||||||
@@ -2134,17 +2133,6 @@ export default function HomePage() {
|
|||||||
};
|
};
|
||||||
}, [funds, refreshMs]);
|
}, [funds, refreshMs]);
|
||||||
|
|
||||||
// 刷新进度条:每 100ms 更新一次进度
|
|
||||||
useEffect(() => {
|
|
||||||
if (funds.length === 0 || refreshMs <= 0) return;
|
|
||||||
const t = setInterval(() => {
|
|
||||||
const elapsed = Date.now() - refreshCycleStartRef.current;
|
|
||||||
const p = Math.min(1, elapsed / refreshMs);
|
|
||||||
setRefreshProgress(p);
|
|
||||||
}, 100);
|
|
||||||
return () => clearInterval(t);
|
|
||||||
}, [funds.length, refreshMs]);
|
|
||||||
|
|
||||||
const performSearch = async (val) => {
|
const performSearch = async (val) => {
|
||||||
if (!val.trim()) {
|
if (!val.trim()) {
|
||||||
setSearchResults([]);
|
setSearchResults([]);
|
||||||
@@ -3447,22 +3435,13 @@ export default function HomePage() {
|
|||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
<div
|
<RefreshButton
|
||||||
className="refresh-btn-wrap"
|
refreshMs={refreshMs}
|
||||||
style={{ '--progress': refreshProgress }}
|
manualRefresh={manualRefresh}
|
||||||
title={`刷新周期 ${Math.round(refreshMs / 1000)} 秒`}
|
refreshing={refreshing}
|
||||||
>
|
fundsLength={funds.length}
|
||||||
<button
|
refreshCycleStartRef={refreshCycleStartRef}
|
||||||
className="icon-button"
|
/>
|
||||||
aria-label="立即刷新"
|
|
||||||
onClick={manualRefresh}
|
|
||||||
disabled={refreshing || funds.length === 0}
|
|
||||||
aria-busy={refreshing}
|
|
||||||
title="立即刷新"
|
|
||||||
>
|
|
||||||
<RefreshIcon className={refreshing ? 'spin' : ''} width="18" height="18" />
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
{/*<button*/}
|
{/*<button*/}
|
||||||
{/* className="icon-button"*/}
|
{/* className="icon-button"*/}
|
||||||
{/* aria-label="打开设置"*/}
|
{/* aria-label="打开设置"*/}
|
||||||
@@ -4296,7 +4275,7 @@ export default function HomePage() {
|
|||||||
{(() => {
|
{(() => {
|
||||||
const showIntraday = Array.isArray(valuationSeries[f.code]) && valuationSeries[f.code].length >= 2;
|
const showIntraday = Array.isArray(valuationSeries[f.code]) && valuationSeries[f.code].length >= 2;
|
||||||
if (!showIntraday) return null;
|
if (!showIntraday) return null;
|
||||||
|
|
||||||
// 如果今日日期大于估值日期,说明是历史估值,不显示分时图
|
// 如果今日日期大于估值日期,说明是历史估值,不显示分时图
|
||||||
if (f.gztime && toTz(todayStr).startOf('day').isAfter(toTz(f.gztime).startOf('day'))) {
|
if (f.gztime && toTz(todayStr).startOf('day').isAfter(toTz(f.gztime).startOf('day'))) {
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
Reference in New Issue
Block a user