perf(web): reschedule route preloads after navigation
This commit is contained in:
@@ -0,0 +1,43 @@
|
||||
import { cleanup, fireEvent, render, screen, waitFor } from '@testing-library/react';
|
||||
import { afterEach, expect, test, vi } from 'vitest';
|
||||
import { MemoryRouter, Route, Routes } from 'react-router-dom';
|
||||
import { ROUTER_FUTURE } from '../routing/routerConfig';
|
||||
|
||||
const routing = vi.hoisted(() => ({
|
||||
preloadRoute: vi.fn(async () => undefined),
|
||||
scheduleIdleRoutePreloads: vi.fn(() => vi.fn()),
|
||||
shouldPreloadRouteOnIntent: vi.fn(() => true)
|
||||
}));
|
||||
|
||||
vi.mock('../routing/routeModules', () => routing);
|
||||
vi.mock('../auth/AuthGate', () => ({
|
||||
usePlatformSession: () => ({ session: { name: 'test-user', role: 'viewer' }, logout: vi.fn() })
|
||||
}));
|
||||
|
||||
import { AppShell } from './AppShell';
|
||||
|
||||
afterEach(() => {
|
||||
cleanup();
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
test('reschedules likely route preloads when the active module changes', async () => {
|
||||
const firstCleanup = vi.fn();
|
||||
const secondCleanup = vi.fn();
|
||||
routing.scheduleIdleRoutePreloads
|
||||
.mockReturnValueOnce(firstCleanup)
|
||||
.mockReturnValueOnce(secondCleanup);
|
||||
|
||||
render(<MemoryRouter future={ROUTER_FUTURE} initialEntries={['/monitor']}>
|
||||
<Routes><Route element={<AppShell />}><Route path="*" element={<span>页面内容</span>} /></Route></Routes>
|
||||
</MemoryRouter>);
|
||||
|
||||
expect(routing.scheduleIdleRoutePreloads).toHaveBeenCalledWith({ activePathname: '/monitor' });
|
||||
fireEvent.click(screen.getByRole('link', { name: '历史数据' }));
|
||||
|
||||
await waitFor(() => expect(routing.scheduleIdleRoutePreloads).toHaveBeenLastCalledWith({ activePathname: '/history' }));
|
||||
expect(firstCleanup).toHaveBeenCalledTimes(1);
|
||||
|
||||
cleanup();
|
||||
expect(secondCleanup).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
@@ -39,11 +39,11 @@ const pageNames: Record<string, string> = {
|
||||
|
||||
export function AppShell() {
|
||||
const location = useLocation();
|
||||
const [initialPathname] = useState(() => location.pathname);
|
||||
const section = location.pathname.split('/')[1] || 'monitor';
|
||||
const activeRoutePath = `/${section}`;
|
||||
const { session, logout } = usePlatformSession();
|
||||
const roleLabel = { viewer: '只读', operator: '处置员', admin: '管理员' }[session.role];
|
||||
useEffect(() => scheduleIdleRoutePreloads({ activePathname: initialPathname }), [initialPathname]);
|
||||
useEffect(() => scheduleIdleRoutePreloads({ activePathname: activeRoutePath }), [activeRoutePath]);
|
||||
|
||||
return (
|
||||
<div className="v2-shell">
|
||||
|
||||
Reference in New Issue
Block a user