perf: lighten routes and improve ai runtime events

This commit is contained in:
2026-06-21 21:01:38 +08:00
parent 0c52bf0641
commit 9647a227da
13 changed files with 130 additions and 74 deletions
-3
View File
@@ -9,7 +9,6 @@ import { preferences } from '@vben/preferences';
import { getAllMenusApi } from '#/api/core/menu';
import { BasicLayout, IFrameView } from '#/layouts';
import { $t } from '#/locales';
import { useAppContextStore } from '#/store/app-context';
import { isLightMenuName } from './light-menu';
@@ -194,8 +193,6 @@ async function generateAccess(options: GenerateMenuAndRoutesOptions) {
'../views/ai-platform/workflow/editor/index.vue',
'../views/ai-platform/workflow/index.vue',
'../views/ai-platform/workflow-runs/index.vue',
'../views/dashboard/analytics/index.vue',
'../views/dashboard/workspace/index.vue',
]);
const layoutMap: ComponentRecordType = {
@@ -1,8 +1,5 @@
export const LIGHT_MENU_NAMES = new Set([
'ControlCenter',
'Dashboard',
'DashboardAnalytics',
'DashboardWorkspace',
'AIAgent',
'AIKnowledgeDetail',
'AIModelConfig',
@@ -26,7 +23,6 @@ export const LIGHT_MENU_NAMES = new Set([
const LIGHT_ROUTE_PATH_PREFIXES = [
'/control-center',
'/dashboard',
'/ai-platform/agent',
'/ai-platform/knowledge',
'/ai-platform/knowledge-base',
+56 -11
View File
@@ -11,20 +11,32 @@ type WindowWithIdleCallback = Window & {
) => IdleCallbackHandle;
};
type NavigatorWithConnection = Navigator & {
connection?: {
effectiveType?: string;
saveData?: boolean;
};
};
let prefetched = false;
const criticalPrefetchTasks = [
() => import('#/views/_core/agent-chat/index.vue'),
() => import('#/views/ai-platform/workflow-runs/index.vue'),
() => import('#/components/ai-chat-panel/AiChatPanel.vue'),
() => import('#/views/ai-platform/workflow-runs/modules/detail-dialog.vue'),
const corePrefetchTasks = [
() => import('#/views/_core/user/index.vue'),
() => import('#/views/_core/menu/index.vue'),
() => import('#/views/_core/role/index.vue'),
];
const deferredPrefetchTasks = [
const aiInteractivePrefetchTasks = [
() => import('#/views/_core/agent-chat/index.vue'),
() => import('#/components/ai-chat-panel/AiChatPanel.vue'),
];
const aiManagementPrefetchTasks = [
() => import('#/views/ai-platform/agent/index.vue'),
() => import('#/views/ai-platform/workflow/index.vue'),
() => import('#/views/ai-platform/model/index.vue'),
() => import('#/views/ai-platform/knowledge/index.vue'),
() => import('#/views/ai-platform/workflow-runs/index.vue'),
];
function scheduleIdle(callback: () => void) {
@@ -38,6 +50,28 @@ function scheduleIdle(callback: () => void) {
window.setTimeout(callback, 1200);
}
function canPrefetch() {
if (typeof document !== 'undefined' && document.visibilityState !== 'visible') {
return false;
}
const connection = (navigator as NavigatorWithConnection).connection;
if (connection?.saveData) {
return false;
}
return !/(^|-)2g$/.test(connection?.effectiveType || '');
}
async function runTasksSequentially(tasks: Array<() => Promise<unknown>>) {
for (const task of tasks) {
if (!canPrefetch()) {
return;
}
await task().catch(() => undefined);
}
}
function prefetchAiPlatformPages() {
if (prefetched || typeof window === 'undefined') {
return;
@@ -45,11 +79,22 @@ function prefetchAiPlatformPages() {
prefetched = true;
window.setTimeout(() => {
void Promise.allSettled(criticalPrefetchTasks.map((task) => task()));
}, 300);
scheduleIdle(() => {
void Promise.allSettled(deferredPrefetchTasks.map((task) => task()));
});
scheduleIdle(() => {
void runTasksSequentially(corePrefetchTasks);
});
}, 800);
window.setTimeout(() => {
scheduleIdle(() => {
void runTasksSequentially(aiInteractivePrefetchTasks);
});
}, 4000);
window.setTimeout(() => {
scheduleIdle(() => {
void runTasksSequentially(aiManagementPrefetchTasks);
});
}, 9000);
}
export { prefetchAiPlatformPages };
@@ -32,6 +32,24 @@ const coreRoutes: RouteRecordRaw[] = [
redirect: preferences.app.defaultHomePath,
children: [],
},
{
meta: { hideInMenu: true, title: '控制中心' },
name: 'DashboardLegacyRedirect',
path: '/dashboard',
redirect: '/page-render/main_home',
},
{
meta: { hideInMenu: true, title: '控制中心' },
name: 'DashboardAnalyticsLegacyRedirect',
path: '/dashboard/analytics',
redirect: '/page-render/main_home',
},
{
meta: { hideInMenu: true, title: '控制中心' },
name: 'DashboardWorkspaceLegacyRedirect',
path: '/dashboard/workspace',
redirect: '/page-render/main_home',
},
{
component: AuthPageLayout,
meta: {
@@ -4,7 +4,6 @@ import { mergeRouteModules, traverseTreeValues } from '@vben/utils';
import { coreRoutes, fallbackNotFoundRoute } from './core';
import aiPlatformRoutes from './modules/ai-platform';
import dashboardRoutes from './modules/dashboard';
// 有需要可以自行打开注释,并创建文件夹
// const externalRouteFiles = import.meta.glob('./external/**/*.ts', { eager: true });
@@ -13,7 +12,6 @@ import dashboardRoutes from './modules/dashboard';
/** 动态路由 */
const dynamicRoutes: RouteRecordRaw[] = mergeRouteModules({
'./modules/ai-platform.ts': { default: aiPlatformRoutes },
'./modules/dashboard.ts': { default: dashboardRoutes },
});
/** 外部路由列表,访问这些页面可以不需要Layout,可能用于内嵌在别的系统(不会显示在菜单中) */
@@ -2,7 +2,7 @@ import type { RouteRecordRaw } from 'vue-router';
const routes: RouteRecordRaw[] = [
{
meta: { hideInMenu: true },
meta: { hideInMenu: true, title: '控制中心' },
name: 'ControlCenterLegacyRedirect',
path: '/control-center',
redirect: '/page-render/main_home',
@@ -17,13 +17,13 @@ const routes: RouteRecordRaw[] = [
component: () => import('#/views/_core/page-render/index.vue'),
},
{
meta: { hideInMenu: true },
meta: { hideInMenu: true, title: '知识库' },
name: 'AIKnowledgeLegacyRedirect',
path: '/ai-platform/knowledge',
redirect: '/ai-platform/knowledge-base',
},
{
meta: { hideInMenu: true },
meta: { hideInMenu: true, title: '知识库' },
name: 'SubAppAIKnowledgeLegacyRedirect',
path: '/app/:appCode/ai-platform/knowledge',
redirect: (to) => `/app/${to.params.appCode}/ai-platform/knowledge-base`,
@@ -65,13 +65,13 @@ const routes: RouteRecordRaw[] = [
component: () => import('#/views/ai-platform/model/index.vue'),
},
{
meta: { hideInMenu: true },
meta: { hideInMenu: true, title: '知识库详情' },
name: 'AIKnowledgeLegacyDetailRedirect',
path: '/ai-platform/knowledge/detail/:id',
redirect: (to) => `/ai-platform/knowledge-base/detail/${to.params.id}`,
},
{
meta: { hideInMenu: true },
meta: { hideInMenu: true, title: '知识库详情' },
name: 'SubAppAIKnowledgeLegacyDetailRedirect',
path: '/app/:appCode/ai-platform/knowledge/detail/:id',
redirect: (to) =>