# 客户端懒加载分块(lazy chunks)设计 > 日期:2026-08-12 > 状态:已实现 > 范围:`dsh-better-sidebar` 插件,客户端 bundle 拆分 ## 1. 背景与问题 改造前客户端是单文件 bundle(`lib/client.js`,约 24.6MB),页面启动时全部**下载 + 解析 + 执行**。实测构成(按 sourcemap 源字节): | 依赖 | 体积 | 用途 | |---|---|---| | `@univerjs/*` 全家桶 + echarts/zrender 等 | ~18MB | .xlsx 预览 | | `@codemirror/*` + `@lezer/*` | ~1.9MB | 文本编辑器高亮 | | `xlsx`(SheetJS) | ~0.6MB | .xlsx 解析 | | `@aiden0z/pptx-renderer` | ~0.5MB | .pptx 预览 | | `xterm` | ~0.3MB | 终端 | | `docx-preview` + `jszip` | ~0.2MB | .docx 预览 | | 插件自身代码 | ~0.35MB | — | 虽然 `office-view.tsx` 用了动态 `import()`,但 `codeSplitting: false` 只保证**延迟执行**(`Promise.resolve().then(() => (init_docx_preview(), ...))`),下载与解析成本仍在启动时;且 `xlsx-to-univer.ts` 对 `@univerjs/presets` 的静态 value-import 让 Univer 核心实际在启动时执行。 **目标**:重依赖拆成独立脚本,首次打开对应功能才下载/解析/执行;启动只拉核心(~325KB)。 ## 2. 机制 chunk 脚本**不经过** `window.__ModuleLoader__` / `ClientModuleSystem.import()` 的物化路径——模块系统的 import() 只解析 seed word / shell-own 模块 / 已注册 factory / boot graph row,chunk id 四者皆非,解析行为依赖 DSH 版本(实测某些版本在 factory 已注册时仍抛 "cannot resolve")。因此改为插件自有的全局 factory 注册表: 1. **构建期**:每个 chunk 是独立 tsdown 浏览器 bundle(`lib/client-.js`),脚本首行为: ```js globalThis.__dshChunks__ = globalThis.__dshChunks__ || {}; globalThis.__dshChunks__["terminal"] = (require) => { /* CJS 闭包体 */ }; ``` 与主 bundle 相同的 externals(react 等走 module table)、纯度门、CSS 内联管线;`codeSplitting: false` 保持单文件。 2. **运行期** `loadChunk(name)`: - 注入 `