perf(web): 路由级懒加载,修复失效 useMemo 与 HMR 全页刷新
- 11 个页面改为 React.lazy;Login 与 MainLayout 保持同步加载(未登录用户与 登录后首帧的必经路径);新增统一占位 RouteFallback,替换权限校验处重复的 div 首屏静态资源 gzip 497.7 kB → 268.4 kB(-46.1%),>500 kB 体积警告消失 - PlatformUsers 的 columns/memberColumns/merchantColumns 每次渲染都重建, 使依赖它们的 items 的 useMemo 完全失效;三个回调 useCallback 化、 三个列定义 useMemo 化,让 memo 真正命中 - useAuth/AuthContext 拆到 store/authContext.ts,使 store/auth.tsx 只导出 AuthProvider 组件,消除 react(only-export-components) 导致的 HMR 整页刷新 (同步更新 7 处引用) - MainLayout 未使用的 catch 参数清理 oxlint:5 warnings → 0 warnings / 0 errors。
This commit is contained in:
+28
-14
@@ -1,21 +1,33 @@
|
||||
import { Suspense, lazy } from 'react'
|
||||
import { BrowserRouter, Navigate, Route, Routes, useLocation } from 'react-router-dom'
|
||||
import { ConfigProvider, App as AntdApp, Spin } from 'antd'
|
||||
import zhCN from 'antd/locale/zh_CN'
|
||||
import { AuthProvider, useAuth } from './store/auth'
|
||||
import { AuthProvider } from './store/auth'
|
||||
import { useAuth } from './store/authContext'
|
||||
import MainLayout from './layouts/MainLayout'
|
||||
import Login from './pages/Login'
|
||||
import Dashboard from './pages/Dashboard'
|
||||
import OpenApiDocs from './pages/OpenApiDocs'
|
||||
import ApiDebugger from './pages/ApiDebugger'
|
||||
import Delivery from './pages/Delivery'
|
||||
import MerchantCenter from './pages/MerchantCenter'
|
||||
import MerchantRecharge from './pages/MerchantRecharge'
|
||||
import AlertSettings from './pages/AlertSettings'
|
||||
import PlatformMerchants from './pages/PlatformMerchants'
|
||||
import PlatformProducts from './pages/PlatformProducts'
|
||||
import PlatformUsers from './pages/PlatformUsers'
|
||||
import PlatformRock from './pages/PlatformRock'
|
||||
import type { ReactNode } from 'react'
|
||||
|
||||
// 路由级懒加载:把原先 1.6MB 的首屏单包按页面拆分。
|
||||
// Login 与 MainLayout 保持同步加载——它们是未登录用户和登录后首帧的必经路径,
|
||||
// 懒加载只会凭空多一次往返。
|
||||
const Dashboard = lazy(() => import('./pages/Dashboard'))
|
||||
const OpenApiDocs = lazy(() => import('./pages/OpenApiDocs'))
|
||||
const ApiDebugger = lazy(() => import('./pages/ApiDebugger'))
|
||||
const Delivery = lazy(() => import('./pages/Delivery'))
|
||||
const MerchantCenter = lazy(() => import('./pages/MerchantCenter'))
|
||||
const MerchantRecharge = lazy(() => import('./pages/MerchantRecharge'))
|
||||
const AlertSettings = lazy(() => import('./pages/AlertSettings'))
|
||||
const PlatformMerchants = lazy(() => import('./pages/PlatformMerchants'))
|
||||
const PlatformProducts = lazy(() => import('./pages/PlatformProducts'))
|
||||
const PlatformUsers = lazy(() => import('./pages/PlatformUsers'))
|
||||
const PlatformRock = lazy(() => import('./pages/PlatformRock'))
|
||||
|
||||
// RouteFallback 是懒加载页面与权限校验的统一占位,避免切换时白屏。
|
||||
function RouteFallback() {
|
||||
return <div style={{ textAlign: 'center', padding: '100px 0' }}><Spin size="large" /></div>
|
||||
}
|
||||
|
||||
function PrivateRoute({ children }: { children: ReactNode }) {
|
||||
const { token } = useAuth()
|
||||
if (!token) return <Navigate to="/login" replace />
|
||||
@@ -41,7 +53,7 @@ function MerchantPermissionRoute({ permission, children }: { permission?: string
|
||||
const { isAdmin, merchantLoading, merchantPermissions } = useAuth()
|
||||
if (isAdmin || !permission) return <>{children}</>
|
||||
if (merchantLoading) {
|
||||
return <div style={{ textAlign: 'center', padding: '100px 0' }}><Spin size="large" /></div>
|
||||
return <RouteFallback />
|
||||
}
|
||||
return merchantPermissions.includes(permission) ? <>{children}</> : <Navigate to="/" replace />
|
||||
}
|
||||
@@ -158,7 +170,9 @@ export default function App() {
|
||||
<AntdApp>
|
||||
<AuthProvider>
|
||||
<BrowserRouter>
|
||||
<AppRoutes />
|
||||
<Suspense fallback={<RouteFallback />}>
|
||||
<AppRoutes />
|
||||
</Suspense>
|
||||
</BrowserRouter>
|
||||
</AuthProvider>
|
||||
</AntdApp>
|
||||
|
||||
Reference in New Issue
Block a user