☰
fast-crud 扩展组件懒加载原理:体积再大也不拖慢首页加载
2026/10/15 11:02:03 网站建设 项目流程
  • 前端
  • 低代码

【免费下载链接】fast-crud

面向配置的crud框架,开发crud 快如闪电,超级表格;Options-oriented crud framework, develop crud as fast as lightning;based on vue3;super table

项目地址:https://gitcode.com/fast-crud/fast-crud
点击查看免费下载

fast-crud(简称 fs)是基于 Vue3 的面向配置的 CRUD 框架,开发 CRUD 快如闪电。它有一个容易被忽略但非常实用的设计:扩展包里的组件全部懒加载。哪怕你安装了上传、富文本、代码编辑器等"重型"扩展包,首页 JS 体积也几乎不变——本文带你 3 步看懂这个懒加载原理,并学会在自己的扩展包里复用它。

为什么扩展组件必须懒加载?

fast-crud 采用"扩展包"机制:上传(uploader)、富文本(editor)、JSON 编辑器、时间格式化等能力被打包成独立 npm 包(位于 packages/fast-extends/、packages/fast-ecology/),安装后只需给字段配置一个类型名(如type: "file-uploader")即可使用。详见 docs/zh/guide/advance/extends.md。

问题在于:monaco-editor、wangEditor、cropperjs 这类依赖动辄几百 KB 到数 MB。如果app.use(FsExtendsUploader)时把所有组件一次性打进主包,用户打开登录页都要下载这些从未用到的代码,首屏自然变慢。

解决方案只有一个词:懒加载——组件代码被拆成独立 chunk,等表单里真正渲染file-uploader字段时才按需下载。

懒加载三步走:从 import.meta.glob 到 defineAsyncComponent

fast-crud 的懒加载机制由 3 个环节串联完成,核心实现在 packages/fast-crud/src/utils/util.vite.ts。

第 1 步:import.meta.glob 声明"待加载组件清单"

扩展包入口不直接 import 组件文件,而是用 Vite 的 import.meta.glob 按通配符收集组件:

// packages/fast-extends/src/uploader/index.ts const asyncModules = import.meta.glob("./components/*.vue"); const FsUploaderComponents = { install(app: any) { // 加载异步组件,异步组件将会被懒加载,所以不用担心打包之后的体积问题 utils.vite.installAsyncComponents(app, asyncModules, ["FsImagesFormat"], null, null); } };

Vite 会把每个匹配到的.vue文件单独拆成一个 chunk。主包里只留下"文件路径 → 加载函数"的映射表,组件源码一个字节都不进主包。

第 2 步:defineAsyncComponent 包装成异步组件

installAsyncComponents内部为清单里的每一项调用 createAsyncComponent,即用 Vue 的defineAsyncComponent把"加载函数"包装成真正的组件:

function createAsyncComponent(es: any) { return defineAsyncComponent({ loader: es, onError(error, retry, fail, attempts) { if (error.message.match(/fetch/) && attempts <= 3) { retry(); // 请求错误时最多重试 3 次 } else { fail(); } } }); }

这里还藏着一个细节:网络抖动自动重试。静态资源加载失败时最多重试 3 次,而不是直接白屏,对弱网环境下的后台系统非常友好。

同时,组件名会通过 transformFromGlob 从文件路径自动推导:fs-uploader-form.vue→FsUploaderForm,注册为全局组件。

第 3 步:按"字符串名字"解析组件,懒加载才真正生效

这是最关键也最容易被误解的一步:扩展包的字段类型配置里,组件是通过字符串名称引用的,例如 types.tsx:

"image-uploader": { form: { component: { name: "fs-file-uploader", // 字符串!不是 import 进来的组件对象 ... } } }

运行期 FsComponentRender 用 Vue 的resolveComponent(name)按名字从全局注册表里取组件。字符串名字不产生任何 import 依赖,因此:

  • 类型配置(type)是同步的小配置,安装时就生效,字段一配置就能用;
  • 组件代码是按需的异步 chunk,只有该字段第一次渲染时才触发下载。

名字解耦了"配置"与"代码",这就是懒加载能彻底生效的原因。

不只是组件:重型依赖也在"懒加载清单"里

同一个思路还贯穿了其他重功能模块,它们都遵循"用到才加载"的原则:

  • Excel 导入导出:loadFsExportUtil 在点击导出按钮时才await import加载导出库,注释写着"加载异步组件,不影响首页加载速度";
  • 代码编辑器:fast-ecology/editor-code 的入口同样用import.meta.glob懒加载组件,monaco 的语言 contribution 也在 async-import.ts 里逐个await import,用户选了哪种语言才加载哪种;
  • 剪贴板复制扩展:copyable/index.ts 是最简范本,import.meta.glob("./components/*.vue")+installAsyncComponents两行搞定。

💡 一个小例外:uploader 扩展中的fs-images-format(列里展示缩略图的轻量组件)用了{ eager: true }同步加载并排除在异步清单之外(index.ts),因为列表页每行都可能用到它,同步加载反而更快。轻量高频组件同步、重型低频组件异步,取舍清晰。

如何给自己的扩展包加上懒加载

如果你想写自定义扩展包,照抄官方模式即可(完整规范见 docs/zh/guide/advance/custom-component.md):

  1. 组件统一放components/*.vue目录;
  2. 入口用import.meta.glob("./components/*.vue")收集,不要逐个import;
  3. 用utils.vite.installAsyncComponents(app, asyncModules, excludes, pickNameExp, transform)注册;
  4. 类型配置中组件用字符串名引用(name: "fs-xxx")。

⚠️ 两个实践提醒:

  • 第三方重型依赖尽量在components/*.vue内部局部引入,别在入口文件顶层 import——入口被同步执行,顶层 import 会直接把依赖打进主包(copyable 中 VueClipboard 因是 directive 需全局注册,属于注释里明确标注的特例);
  • installAsyncComponents基于 Vite 的import.meta.glob,适用于 Vite 生态;UMD 构建版本对应改用了eager: true的同步加载方式(如 copyable/index.umd.ts)。

小结

环节手段效果
收集组件import.meta.glob通配符每个组件独立 chunk
注册组件defineAsyncComponent+ 重试机制首次渲染才下载,弱网自动重试
引用组件字符串名 +resolveComponent配置与代码解耦,零 import 依赖

fast-crud 用这三步,让"扩展越多、体积越大"不再等于"首页越慢"。对于由几十个 CRUD 页面组成的中大型后台系统,这种按需加载策略是首屏性能的重要保障。

延伸阅读

  • 扩展包机制:docs/zh/guide/advance/extends.md
  • 上传扩展用法:docs/zh/guide/extends/uploader.md
  • 编辑器扩展(monaco 按需加载实例):docs/zh/guide/extends/editor.md
  • 集成到你的项目:docs/zh/guide/start/integration.md
  • 前端
  • 低代码

【免费下载链接】fast-crud

面向配置的crud框架,开发crud 快如闪电,超级表格;Options-oriented crud framework, develop crud as fast as lightning;based on vue3;super table

项目地址:https://gitcode.com/fast-crud/fast-crud
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询