mirror of
https://github.com/clash-verge-rev/clash-verge-rev.git
synced 2026-10-30 18:52:12 +08:00
fix(frontend): warm lazy routes concurrently after idle
Start all navigation route preloads after a single idle gate and show centered loading fallbacks during cold route loads.
This commit is contained in:
+16
-6
@@ -39,7 +39,7 @@ import { Outlet, useLocation, useNavigate } from 'react-router'
|
||||
import iconDark from '@/assets/image/icon_dark.svg?react'
|
||||
import iconLight from '@/assets/image/icon_light.svg?react'
|
||||
import LogoSvg from '@/assets/image/logo.svg?react'
|
||||
import { BaseErrorBoundary } from '@/components/base'
|
||||
import { BaseErrorBoundary, BaseLoading } from '@/components/base'
|
||||
import { LayoutItem } from '@/components/layout/layout-item'
|
||||
import { LayoutTraffic } from '@/components/layout/layout-traffic'
|
||||
import { NoticeManager } from '@/components/layout/notice-manager'
|
||||
@@ -240,13 +240,10 @@ const Layout = () => {
|
||||
}
|
||||
|
||||
const controller = new AbortController()
|
||||
const timerId = window.setTimeout(() => {
|
||||
void preloadNavigationRoutes(controller.signal)
|
||||
}, 2000)
|
||||
void preloadNavigationRoutes(controller.signal)
|
||||
|
||||
return () => {
|
||||
controller.abort()
|
||||
window.clearTimeout(timerId)
|
||||
}
|
||||
}, [themeReady, pageVisible])
|
||||
|
||||
@@ -501,7 +498,20 @@ const Layout = () => {
|
||||
bottom: 0,
|
||||
}}
|
||||
>
|
||||
<Suspense fallback={null}>
|
||||
<Suspense
|
||||
fallback={
|
||||
<Box
|
||||
sx={{
|
||||
display: 'flex',
|
||||
height: '100%',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
}}
|
||||
>
|
||||
<BaseLoading />
|
||||
</Box>
|
||||
}
|
||||
>
|
||||
<LogsPage />
|
||||
</Suspense>
|
||||
</div>
|
||||
|
||||
+26
-29
@@ -6,6 +6,7 @@ import LockOpenRoundedIcon from '@mui/icons-material/LockOpenRounded'
|
||||
import SettingsRoundedIcon from '@mui/icons-material/SettingsRounded'
|
||||
import SubjectRoundedIcon from '@mui/icons-material/SubjectRounded'
|
||||
import WifiRoundedIcon from '@mui/icons-material/WifiRounded'
|
||||
import { Box } from '@mui/material'
|
||||
import { lazy, Suspense, type ComponentType } from 'react'
|
||||
import { createBrowserRouter, RouteObject } from 'react-router'
|
||||
|
||||
@@ -17,6 +18,7 @@ import ProxiesSvg from '@/assets/image/itemicon/proxies.svg?react'
|
||||
import RulesSvg from '@/assets/image/itemicon/rules.svg?react'
|
||||
import SettingsSvg from '@/assets/image/itemicon/settings.svg?react'
|
||||
import UnlockSvg from '@/assets/image/itemicon/unlock.svg?react'
|
||||
import { BaseLoading } from '@/components/base'
|
||||
import { ensureLanguageSections } from '@/services/i18n'
|
||||
|
||||
import Layout from './_layout'
|
||||
@@ -91,7 +93,20 @@ const createLazyRoute = (
|
||||
const preload = createRoutePreload(load, sections)
|
||||
const Component = lazy(preload)
|
||||
const LazyRoute = () => (
|
||||
<Suspense fallback={null}>
|
||||
<Suspense
|
||||
fallback={
|
||||
<Box
|
||||
sx={{
|
||||
display: 'flex',
|
||||
height: '100%',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
}}
|
||||
>
|
||||
<BaseLoading />
|
||||
</Box>
|
||||
}
|
||||
>
|
||||
<Component />
|
||||
</Suspense>
|
||||
)
|
||||
@@ -156,36 +171,18 @@ export const navItems = [
|
||||
},
|
||||
]
|
||||
|
||||
const navigationWarmupPriority = ['/connections', '/logs', '/rules']
|
||||
|
||||
const navigationWarmupItems = [...navItems].sort((left, right) => {
|
||||
const leftIndex = navigationWarmupPriority.indexOf(left.path)
|
||||
const rightIndex = navigationWarmupPriority.indexOf(right.path)
|
||||
const leftRank =
|
||||
leftIndex === -1 ? navigationWarmupPriority.length : leftIndex
|
||||
const rightRank =
|
||||
rightIndex === -1 ? navigationWarmupPriority.length : rightIndex
|
||||
|
||||
return leftRank - rightRank
|
||||
})
|
||||
|
||||
export const preloadNavigationRoutes = async (signal: AbortSignal) => {
|
||||
for (const item of navigationWarmupItems) {
|
||||
if (signal.aborted) {
|
||||
return
|
||||
}
|
||||
const preload = 'preload' in item ? item.preload : undefined
|
||||
if (!preload) {
|
||||
continue
|
||||
}
|
||||
|
||||
await waitForWarmupIdle(signal)
|
||||
if (signal.aborted) {
|
||||
return
|
||||
}
|
||||
|
||||
await preload().catch(() => {})
|
||||
await waitForWarmupIdle(signal)
|
||||
if (signal.aborted) {
|
||||
return
|
||||
}
|
||||
|
||||
await Promise.all(
|
||||
navItems.map((item) => {
|
||||
const preload = 'preload' in item ? item.preload : undefined
|
||||
return preload?.().catch(() => {})
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
export const router = createBrowserRouter([
|
||||
|
||||
Reference in New Issue
Block a user