perf(web): warm every primary route

This commit is contained in:
lingniu
2026-07-16 02:35:10 +08:00
parent d140a9782b
commit 7396544269
3 changed files with 21 additions and 11 deletions

View File

@@ -21,14 +21,14 @@ describe('route module preloading', () => {
expect(shouldPreloadRoutes({ effectiveType: '4g' })).toBe(true);
});
it('warms inactive routes one idle period at a time and stops after cleanup', async () => {
it('warms every inactive primary route in bounded idle batches and stops after cleanup', async () => {
const callbacks: Array<() => void> = [];
const cancelled: number[] = [];
const schedule = vi.fn((callback: () => void) => {
const index = callbacks.push(callback) - 1;
return () => { cancelled.push(index); };
});
const preload = vi.fn(async () => undefined);
const preload = vi.fn(async (_pathname: string) => undefined);
const cleanup = scheduleIdleRoutePreloads({
activePathname: '/monitor',
connection: { effectiveType: '4g' },
@@ -39,13 +39,22 @@ describe('route module preloading', () => {
expect(schedule).toHaveBeenCalledTimes(1);
callbacks[0]();
await flushPreloadQueue();
expect(preload).toHaveBeenCalledWith('/tracks');
expect(preload.mock.calls.map(([path]) => path)).toEqual(['/vehicles', '/tracks']);
expect(schedule).toHaveBeenCalledTimes(2);
callbacks[1]();
await flushPreloadQueue();
expect(preload).toHaveBeenLastCalledWith('/history');
expect(preload.mock.calls.map(([path]) => path)).toEqual(['/vehicles', '/tracks', '/history', '/statistics']);
callbacks[2]();
await flushPreloadQueue();
callbacks[3]();
await flushPreloadQueue();
expect(preload.mock.calls.map(([path]) => path)).toEqual([
'/vehicles', '/tracks', '/history', '/statistics', '/alerts', '/access', '/operations'
]);
cleanup();
expect(cancelled).toContain(2);
expect(cancelled).toContain(4);
});
});

View File

@@ -18,8 +18,9 @@ const importers: Record<RouteSection, () => Promise<RouteModule>> = {
const pendingModules = new Map<RouteSection, Promise<RouteModule>>();
const backgroundPreloadOrder: RouteSection[] = [
'monitor', 'tracks', 'history', 'statistics'
'monitor', 'vehicles', 'tracks', 'history', 'statistics', 'alerts', 'access', 'operations'
];
const backgroundPreloadBatchSize = 2;
function loadRoute(section: RouteSection) {
const pending = pendingModules.get(section);
@@ -84,11 +85,9 @@ export function scheduleIdleRoutePreloads({
const warmNext = () => {
if (cancelled) return;
const section = queue.shift();
if (!section) return;
void Promise.resolve()
.then(() => preload(`/${section}`))
.catch(() => undefined)
const batch = queue.splice(0, backgroundPreloadBatchSize);
if (!batch.length) return;
void Promise.allSettled(batch.map((section) => Promise.resolve().then(() => preload(`/${section}`))))
.finally(() => {
if (!cancelled) cancelScheduled = schedule(warmNext);
});