Optimize frontend performance and add route-level web vitals tracking

This commit is contained in:
2569718930@qq.com
2026-03-18 20:38:43 +08:00
parent f0fcb1e379
commit 69f24ddc08
21 changed files with 503 additions and 1386 deletions
+95 -45
View File
@@ -612,10 +612,42 @@ export function AccountCenter() {
const [paymentError, setPaymentError] = useState("");
const [lastIntentId, setLastIntentId] = useState("");
const [lastTxHash, setLastTxHash] = useState("");
const [showSecondarySections, setShowSecondarySections] = useState(false);
const supabaseReady = hasSupabasePublicEnv();
const walletConnectEnabled = Boolean(WALLETCONNECT_PROJECT_ID);
useEffect(() => {
let canceled = false;
let timeoutId: number | null = null;
let idleId: number | null = null;
const win = typeof window !== "undefined" ? (window as any) : null;
const reveal = () => {
if (!canceled) {
setShowSecondarySections(true);
}
};
if (win && typeof win.requestIdleCallback === "function") {
idleId = win.requestIdleCallback(reveal, { timeout: 320 });
} else if (typeof window !== "undefined") {
timeoutId = window.setTimeout(reveal, 140);
} else {
setShowSecondarySections(true);
}
return () => {
canceled = true;
if (win && idleId != null && typeof win.cancelIdleCallback === "function") {
win.cancelIdleCallback(idleId);
}
if (timeoutId != null && typeof window !== "undefined") {
window.clearTimeout(timeoutId);
}
};
}, []);
/**
* Returns a valid access token, refreshing the session if the stored one
* is missing or close to expiry. Throws if the user is not authenticated.
@@ -1826,55 +1858,66 @@ export function AccountCenter() {
</div>
{/* Weekly Ranking Motivation */}
<div className="lg:col-span-4 bg-gradient-to-br from-indigo-600/20 to-purple-600/20 border border-indigo-500/30 rounded-[2.5rem] p-6 flex flex-col justify-between shadow-xl">
<div>
<h3 className="text-lg font-bold flex items-center gap-2 text-white mb-6">
<Sparkles size={20} className="text-yellow-400" />{" "}
{copy.weeklyRewards}
</h3>
<div className="space-y-3">
<div className="flex items-center justify-between p-3 bg-white/5 rounded-xl border border-white/5">
<span className="text-sm flex items-center gap-2">
<div className="w-5 h-5 bg-yellow-500 rounded text-black font-bold text-[10px] flex items-center justify-center">
1
</div>{" "}
Top 1
</span>
<span className="text-xs font-bold text-yellow-500">
+500 & 7Pro
</span>
</div>
<div className="flex items-center justify-between p-3 bg-white/5 rounded-xl border border-white/5">
<span className="text-sm flex items-center gap-2">
<div className="w-5 h-5 bg-slate-300 rounded text-black font-bold text-[10px] flex items-center justify-center">
2
</div>{" "}
Top 2-3
</span>
<span className="text-xs font-bold text-slate-300">
+300 & 3Pro
</span>
</div>
<div className="flex items-center justify-between p-3 bg-white/5 rounded-xl border border-white/5">
<span className="text-sm flex items-center gap-2">
<div className="w-5 h-5 bg-orange-800 rounded text-white font-bold text-[10px] flex items-center justify-center">
4
</div>{" "}
Top 4-10
</span>
<span className="text-xs font-bold text-orange-400">
+150
</span>
{showSecondarySections ? (
<div className="lg:col-span-4 bg-gradient-to-br from-indigo-600/20 to-purple-600/20 border border-indigo-500/30 rounded-[2.5rem] p-6 flex flex-col justify-between shadow-xl">
<div>
<h3 className="text-lg font-bold flex items-center gap-2 text-white mb-6">
<Sparkles size={20} className="text-yellow-400" />{" "}
{copy.weeklyRewards}
</h3>
<div className="space-y-3">
<div className="flex items-center justify-between p-3 bg-white/5 rounded-xl border border-white/5">
<span className="text-sm flex items-center gap-2">
<div className="w-5 h-5 bg-yellow-500 rounded text-black font-bold text-[10px] flex items-center justify-center">
1
</div>{" "}
Top 1
</span>
<span className="text-xs font-bold text-yellow-500">
+500 & 7Pro
</span>
</div>
<div className="flex items-center justify-between p-3 bg-white/5 rounded-xl border border-white/5">
<span className="text-sm flex items-center gap-2">
<div className="w-5 h-5 bg-slate-300 rounded text-black font-bold text-[10px] flex items-center justify-center">
2
</div>{" "}
Top 2-3
</span>
<span className="text-xs font-bold text-slate-300">
+300 & 3Pro
</span>
</div>
<div className="flex items-center justify-between p-3 bg-white/5 rounded-xl border border-white/5">
<span className="text-sm flex items-center gap-2">
<div className="w-5 h-5 bg-orange-800 rounded text-white font-bold text-[10px] flex items-center justify-center">
4
</div>{" "}
Top 4-10
</span>
<span className="text-xs font-bold text-orange-400">
+150
</span>
</div>
</div>
</div>
<div className="mt-6 flex items-start gap-2 p-3 bg-black/20 rounded-xl">
<Info size={14} className="text-slate-500 mt-0.5 shrink-0" />
<p className="text-[10px] text-slate-500 leading-normal italic">
</p>
</div>
</div>
<div className="mt-6 flex items-start gap-2 p-3 bg-black/20 rounded-xl">
<Info size={14} className="text-slate-500 mt-0.5 shrink-0" />
<p className="text-[10px] text-slate-500 leading-normal italic">
</p>
) : (
<div className="lg:col-span-4 rounded-[2.5rem] border border-white/10 bg-white/5 p-6">
<div className="h-6 w-40 animate-pulse rounded bg-slate-800/80" />
<div className="mt-4 space-y-2">
<div className="h-12 animate-pulse rounded-xl bg-slate-800/60" />
<div className="h-12 animate-pulse rounded-xl bg-slate-800/60" />
<div className="h-12 animate-pulse rounded-xl bg-slate-800/60" />
</div>
</div>
</div>
)}
{/* Subscription Info & Paywall */}
<div className="lg:col-span-12 relative">
@@ -1966,6 +2009,7 @@ export function AccountCenter() {
</div>
{/* Telegram Bot Section */}
{showSecondarySections ? (
<div className="lg:col-span-12 grid grid-cols-1 md:flex gap-6">
<section className="flex-1 bg-white/5 border border-white/10 rounded-[2rem] p-8 relative overflow-hidden group">
<Bot
@@ -2142,6 +2186,12 @@ export function AccountCenter() {
</div>
</section>
</div>
) : (
<div className="lg:col-span-12 grid grid-cols-1 gap-6 md:grid-cols-3">
<div className="md:col-span-2 h-48 animate-pulse rounded-[2rem] border border-white/10 bg-white/5" />
<div className="h-48 animate-pulse rounded-[2rem] border border-white/10 bg-white/5" />
</div>
)}
</main>
<footer className="mt-16 text-center text-slate-600 text-[10px] uppercase tracking-[0.3em] font-mono z-10 pb-8">
@@ -0,0 +1,29 @@
"use client";
import dynamic from "next/dynamic";
const AccountCenter = dynamic(
() =>
import("@/components/account/AccountCenter").then(
(module) => module.AccountCenter,
),
{
ssr: false,
loading: () => (
<div className="min-h-screen bg-slate-950 text-slate-300">
<div className="mx-auto w-full max-w-6xl px-6 py-10">
<div className="h-7 w-48 animate-pulse rounded bg-slate-800/80" />
<div className="mt-6 grid grid-cols-1 gap-4 md:grid-cols-3">
<div className="h-32 animate-pulse rounded-3xl bg-slate-800/70 md:col-span-2" />
<div className="h-32 animate-pulse rounded-3xl bg-slate-800/70" />
</div>
<div className="mt-6 h-72 animate-pulse rounded-3xl bg-slate-800/60" />
</div>
</div>
),
},
);
export function AccountEntry() {
return <AccountCenter />;
}