perf: improve admin page cold starts

This commit is contained in:
2026-06-22 12:05:17 +08:00
parent c5d9bac0ed
commit c8756be02e
8 changed files with 284 additions and 34 deletions
+33 -16
View File
@@ -11,6 +11,7 @@ import { getAllMenusApi } from '#/api/core/menu';
import { BasicLayout, IFrameView } from '#/layouts';
import { useAppContextStore } from '#/store/app-context';
import { createAdminRuntimePage } from './admin-runtime-page';
import { isLightMenuName } from './light-menu';
const forbiddenComponent = () => import('#/views/_core/fallback/forbidden.vue');
@@ -71,16 +72,29 @@ function createLightAiMenuRoute(
return route as RouteRecordStringComponent;
}
const PREFETCH_LIGHT_PAGE_KEYS = [
'../views/_core/agent-chat/index.vue',
const ADMIN_RUNTIME_PAGE_KEYS = new Set([
'../views/_core/menu/index.vue',
'../views/_core/page-render/index.vue',
'../views/_core/permission/index.vue',
'../views/_core/role/index.vue',
'../views/_core/user/index.vue',
'../views/ai-platform/agent/index.vue',
'../views/ai-platform/model/index.vue',
'../views/ai-platform/workflow-runs/index.vue',
'../views/ai-platform/workflow/index.vue',
]);
function withAdminRuntimePages(pageMap: ComponentRecordType) {
return Object.fromEntries(
Object.entries(pageMap).map(([key, loader]) => [
key,
ADMIN_RUNTIME_PAGE_KEYS.has(key) && typeof loader === 'function'
? createAdminRuntimePage(loader as () => Promise<{ default: any }>)
: loader,
]),
) as ComponentRecordType;
}
const PREFETCH_LIGHT_PAGE_KEYS = [
'../views/_core/menu/index.vue',
'../views/_core/role/index.vue',
'../views/_core/user/index.vue',
];
let lightPagesPrefetched = false;
@@ -89,23 +103,25 @@ function scheduleIdleTask(callback: () => void) {
if (typeof window === 'undefined') return;
const requestIdle = (window as any).requestIdleCallback;
if (typeof requestIdle === 'function') {
requestIdle(callback, { timeout: 3000 });
requestIdle(callback, { timeout: 8000 });
return;
}
window.setTimeout(callback, 1200);
window.setTimeout(callback, 8000);
}
function prefetchLightPages(pageMap: ComponentRecordType) {
if (lightPagesPrefetched) return;
lightPagesPrefetched = true;
scheduleIdleTask(() => {
for (const key of PREFETCH_LIGHT_PAGE_KEYS) {
const loader = pageMap[key];
if (typeof loader === 'function') {
void loader().catch(() => undefined);
window.setTimeout(() => {
scheduleIdleTask(() => {
for (const key of PREFETCH_LIGHT_PAGE_KEYS) {
const loader = pageMap[key];
if (typeof loader === 'function') {
void loader().catch(() => undefined);
}
}
}
});
});
}, 12_000);
}
const LIGHT_AI_PLATFORM_MENU_ROUTES = [
@@ -225,7 +241,7 @@ function filterAvailableRoutes<
}
async function generateAccess(options: GenerateMenuAndRoutesOptions) {
const pageMap: ComponentRecordType = import.meta.glob([
const rawPageMap: ComponentRecordType = import.meta.glob([
'../views/_core/account-settings/index.vue',
'../views/_core/agent-chat/**/*.vue',
'../views/_core/announcement/index.vue',
@@ -247,6 +263,7 @@ async function generateAccess(options: GenerateMenuAndRoutesOptions) {
'../views/ai-platform/workflow/index.vue',
'../views/ai-platform/workflow-runs/index.vue',
]);
const pageMap = withAdminRuntimePages(rawPageMap);
const layoutMap: ComponentRecordType = {
BasicLayout,