perf(frontend): replace blank Suspense fallbacks with Spin, switch to matchMedia hook, add virtual table scrolling (#6187)

- routes.tsx, LazyMount.tsx: replace Suspense fallback={null} with Spin
  loader so page transitions and lazy modals never show blank content
- useMediaQuery.ts: switch from resize event to matchMedia change event,
  eliminating state updates on every pixel drag; export MOBILE_BREAKPOINT_PX
- SubPage.tsx: drop duplicate inline isMobile logic (7 lines), use shared
  useMediaQuery(576) (2 lines)
- ClientsPage, InboundList, HostList, NodeList: add virtual + scroll.y to
  Table for viewport-only DOM rendering of large datasets
This commit is contained in:
PathGao
2026-08-15 22:44:08 +08:00
committed by GitHub
parent 0f14ce7551
commit 8e7fb144ee
8 changed files with 42 additions and 20 deletions
@@ -1,4 +1,5 @@
import { Suspense, useEffect, useState, type ReactNode } from 'react';
import { Spin } from 'antd';
interface LazyMountProps {
when: boolean;
@@ -10,7 +11,7 @@ interface LazyMountProps {
// thereafter, so React.lazy modals get loaded on demand but their close
// animations still play out. Pair with `lazy(() => import(...))` modal imports
// on heavy list pages to keep the initial bundle small.
export default function LazyMount({ when, fallback = null, children }: LazyMountProps) {
export default function LazyMount({ when, fallback = <Spin />, children }: LazyMountProps) {
const [mounted, setMounted] = useState(when);
useEffect(() => {
if (when && !mounted) setMounted(true);