perf: optimize bootstrap modules to speed up first-screen loading (#5899)

优化首屏加载速度
This commit is contained in:
Netfan
2025-04-09 01:05:20 +08:00
committed by GitHub
parent 9379093a4f
commit 329a176a5c
13 changed files with 311 additions and 115 deletions

View File

@@ -8,35 +8,64 @@ import type { Component } from 'vue';
import type { BaseFormComponentType } from '@vben/common-ui';
import type { Recordable } from '@vben/types';
import { defineComponent, getCurrentInstance, h, ref } from 'vue';
import {
defineAsyncComponent,
defineComponent,
getCurrentInstance,
h,
ref,
} from 'vue';
import { ApiComponent, globalShareState, IconPicker } from '@vben/common-ui';
import { $t } from '@vben/locales';
import {
AutoComplete,
Button,
Checkbox,
CheckboxGroup,
DatePicker,
Divider,
Input,
InputNumber,
InputPassword,
Mentions,
notification,
Radio,
RadioGroup,
RangePicker,
Rate,
Select,
Space,
Switch,
Textarea,
TimePicker,
TreeSelect,
Upload,
} from 'ant-design-vue';
import { notification } from 'ant-design-vue';
const AutoComplete = defineAsyncComponent(
() => import('ant-design-vue/es/auto-complete'),
);
const Button = defineAsyncComponent(() => import('ant-design-vue/es/button'));
const Checkbox = defineAsyncComponent(
() => import('ant-design-vue/es/checkbox'),
);
const CheckboxGroup = defineAsyncComponent(() =>
import('ant-design-vue/es/checkbox').then((res) => res.CheckboxGroup),
);
const DatePicker = defineAsyncComponent(
() => import('ant-design-vue/es/date-picker'),
);
const Divider = defineAsyncComponent(() => import('ant-design-vue/es/divider'));
const Input = defineAsyncComponent(() => import('ant-design-vue/es/input'));
const InputNumber = defineAsyncComponent(
() => import('ant-design-vue/es/input-number'),
);
const InputPassword = defineAsyncComponent(() =>
import('ant-design-vue/es/input').then((res) => res.InputPassword),
);
const Mentions = defineAsyncComponent(
() => import('ant-design-vue/es/mentions'),
);
const Radio = defineAsyncComponent(() => import('ant-design-vue/es/radio'));
const RadioGroup = defineAsyncComponent(() =>
import('ant-design-vue/es/radio').then((res) => res.RadioGroup),
);
const RangePicker = defineAsyncComponent(() =>
import('ant-design-vue/es/date-picker').then((res) => res.RangePicker),
);
const Rate = defineAsyncComponent(() => import('ant-design-vue/es/rate'));
const Select = defineAsyncComponent(() => import('ant-design-vue/es/select'));
const Space = defineAsyncComponent(() => import('ant-design-vue/es/space'));
const Switch = defineAsyncComponent(() => import('ant-design-vue/es/switch'));
const Textarea = defineAsyncComponent(() =>
import('ant-design-vue/es/input').then((res) => res.Textarea),
);
const TimePicker = defineAsyncComponent(
() => import('ant-design-vue/es/time-picker'),
);
const TreeSelect = defineAsyncComponent(
() => import('ant-design-vue/es/tree-select'),
);
const Upload = defineAsyncComponent(() => import('ant-design-vue/es/upload'));
const withDefaultPlaceholder = <T extends Component>(
component: T,

View File

@@ -1,14 +1,12 @@
import { createApp, watchEffect } from 'vue';
import { registerAccessDirective } from '@vben/access';
import { initTippy, registerLoadingDirective } from '@vben/common-ui';
import { MotionPlugin } from '@vben/plugins/motion';
import { registerLoadingDirective } from '@vben/common-ui';
import { preferences } from '@vben/preferences';
import { initStores } from '@vben/stores';
import '@vben/styles';
import '@vben/styles/antd';
import { VueQueryPlugin } from '@tanstack/vue-query';
import { useTitle } from '@vueuse/core';
import { $t, setupI18n } from '#/locales';
@@ -21,13 +19,13 @@ async function bootstrap(namespace: string) {
// 初始化组件适配器
await initComponentAdapter();
// // 设置弹窗的默认配置
// 设置弹窗的默认配置
// setDefaultModalProps({
// fullscreenButton: false,
// });
// // 设置抽屉的默认配置
// 设置抽屉的默认配置
// setDefaultDrawerProps({
// // zIndex: 1020,
// zIndex: 1020,
// });
const app = createApp(App);
@@ -48,15 +46,18 @@ async function bootstrap(namespace: string) {
registerAccessDirective(app);
// 初始化 tippy
const { initTippy } = await import('@vben/common-ui/es/tippy');
initTippy(app);
// 配置路由及路由守卫
app.use(router);
// 配置@tanstack/vue-query
const { VueQueryPlugin } = await import('@tanstack/vue-query');
app.use(VueQueryPlugin);
// 配置Motion插件
const { MotionPlugin } = await import('@vben/plugins/motion');
app.use(MotionPlugin);
// 动态更新标题

View File

@@ -2,10 +2,10 @@ import type { RouteRecordRaw } from 'vue-router';
import { DEFAULT_HOME_PATH, LOGIN_PATH } from '@vben/constants';
import { AuthPageLayout, BasicLayout } from '#/layouts';
import { $t } from '#/locales';
import Login from '#/views/_core/authentication/login.vue';
const BasicLayout = () => import('#/layouts/basic.vue');
const AuthPageLayout = () => import('#/layouts/auth.vue');
/** 全局404页面 */
const fallbackNotFoundRoute: RouteRecordRaw = {
component: () => import('#/views/_core/fallback/not-found.vue'),
@@ -50,7 +50,7 @@ const coreRoutes: RouteRecordRaw[] = [
{
name: 'Login',
path: 'login',
component: Login,
component: () => import('#/views/_core/authentication/login.vue'),
meta: {
title: $t('page.auth.login'),
},