|
84 | 84 | - **Mermaid**: |
85 | 85 | - **问题**:直接 `import('mermaid')` 会引入依赖 `import.meta.url` 的源码,导致 Webpack 构建警告或运行时错误。 |
86 | 86 | - **解决方案**:强制引入预编译的 UMD/Minified 版本: |
| 87 | + |
87 | 88 | ```javascript |
88 | 89 | import('mermaid/dist/mermaid.min.js') |
89 | 90 | ``` |
| 91 | + |
90 | 92 | - **Remark/Rehype 插件**: |
91 | 93 | - **问题**:在生产模式下,动态导入的插件可能被包装为 Module Namespace 对象(`{ default: fn, ... }`),直接作为函数调用会导致崩溃。 |
92 | 94 | - **解决方案**:在使用前进行兼容性解包: |
| 95 | + |
93 | 96 | ```javascript |
94 | 97 | const plugin = importedPlugin?.default || importedPlugin; |
95 | 98 | ``` |
96 | 99 |
|
| 100 | +## 本次构建体积分布(2026-03-09) |
| 101 | + |
| 102 | +本节基于以下命令的实际产物与 stats 分析: |
| 103 | + |
| 104 | +```bash |
| 105 | +SKIP_OPTIMIZE_MEDIA=1 npm run build:production |
| 106 | +``` |
| 107 | + |
| 108 | +### 主要超大产物 |
| 109 | + |
| 110 | +- `dist/static/js/app.*.js`:约 5.0 MiB(gzip 后约 1.5 MiB) |
| 111 | +- `dist/static/js/9861.*.js`:约 2.9 MiB,对应 `mermaid/dist/mermaid.min.js` |
| 112 | +- `dist/static/js/6416.*.js`:约 1.2 MiB(未压缩约 4.25 MiB),对应 `echarts/index.js + 571 modules` |
| 113 | +- `dist/static/js/vendor-hls.*.js`:约 528 KiB,对应 `hls.js/dist/hls.mjs` |
| 114 | +- `dist/d52ec1a71b0b003c7892.mjs`:约 1.0 MiB,对应 `pdfjs-dist/build/pdf.worker.min.mjs` |
| 115 | +- `dist/images/732165aa59baa0e9674e.mp4`:约 4.2 MiB,对应 `src/assets-optimized/video/trailer.mp4` |
| 116 | +- `dist/images/3b69854a302e6128ab4d.mp3`:约 4.0 MiB,对应 `src/assets-optimized/audio/longnight.mp3` |
| 117 | +- `dist/images/2c1a073543dd765ee06c.mp3`:约 3.9 MiB,对应 `src/assets-optimized/audio/yesterday.mp3` |
| 118 | +- `dist/images/45067c353c9c3e4ed796.mp3`:约 3.5 MiB,对应 `src/assets-optimized/audio/hearty.mp3` |
| 119 | +- `dist/images/2152655c1d61800e86a3.mp3`:约 2.0 MiB,对应 `src/assets-optimized/audio/heart-of-the-sea.mp3` |
| 120 | +- `dist/images/f5fb3175e80af3f631cc.png`:约 1.4 MiB,对应 `src/assets/images/spring.png` |
| 121 | +- `dist/images/916ddb5adf113a8dd7a3.png`:约 1.1 MiB,对应 `src/assets/images/he.png` |
| 122 | +- `dist/images/695c6a7e4d55286b3565.png`:约 1.0 MiB,对应 `src/assets/images/song.png` |
| 123 | +- `dist/images/9ce539741014a14d8c0c.png`:约 909 KiB,对应 `src/assets/images/xue.png` |
| 124 | + |
| 125 | +### 主要来源归因 |
| 126 | + |
| 127 | +#### 1) 音频资源块过大 |
| 128 | + |
| 129 | +- 来源:`src/components/stateless/FixMusicPlayer/data/songs.js` |
| 130 | +- 影响:`ReactMusic` 页面对应 chunk 里直接带入 4 首本地 mp3,总体超过 14 MiB。 |
| 131 | +- 现状:`songs.js` 在模块顶层直接 import 本地音频与封面图,构建时会稳定打进产物。 |
| 132 | + |
| 133 | +#### 2) 视频资源块过大 |
| 134 | + |
| 135 | +- 来源:`src/pages/video/index.jsx` 与 `src/components/stateless/LandingPage/index.jsx` |
| 136 | +- 影响:同一份 `trailer.mp4` 约 4.2 MiB,且属于本地静态资源,不经过自适应码率或 CDN 流式分发。 |
| 137 | + |
| 138 | +#### 3) 首页同步带入 PDF Worker |
| 139 | + |
| 140 | +- 来源:`src/pages/home/index.jsx` 同步 import `InteractiveBook` |
| 141 | +- 影响:额外产出约 1.0 MiB 的 `pdf.worker.min.mjs`,即使用户不打开 PDF 书籍功能,也会随站点发布。 |
| 142 | + |
| 143 | +#### 4) ChatGPT 页面块偏重 |
| 144 | + |
| 145 | +- 来源:`src/pages/chatgpt/index.jsx` |
| 146 | +- 主要组成: |
| 147 | + - 页面自身及关联模块约 1.5 MiB |
| 148 | + - Mermaid 独立 chunk 约 2.9 MiB |
| 149 | + - `react-markdown` / `remark-parse` / `remark-rehype` / `unified` 等 markdown 管线被拉入公共路径 |
| 150 | + |
| 151 | +#### 5) ECharts 使用全量入口 |
| 152 | + |
| 153 | +- 来源:`src/pages/echarts/index.jsx` |
| 154 | +- 现状:当前打入的是 `echarts/index.js + 571 modules`,未做按需引入。 |
| 155 | + |
| 156 | +#### 6) 菜单 hover 预加载会放大“懒加载页面”的实际网络成本 |
| 157 | + |
| 158 | +- 触发点:`src/pages/layout/proSecNav/index.jsx` |
| 159 | +- 现状:菜单项 hover 时会执行 `comp.preload()` 与页面模块预取。 |
| 160 | +- 影响:即便页面路由本身是懒加载,用户悬停菜单后仍可能提前下载 `ChatGpt`、`Echarts`、`ReactMusic`、`MyVideo` 等重页面资源。 |
| 161 | + |
| 162 | +## 具体瘦身建议 |
| 163 | + |
| 164 | +### 优先级 P0:先处理媒体资源 |
| 165 | + |
| 166 | +- 将 `FixMusicPlayer` 的歌曲清单从“顶层静态 import”改为“元数据 + 点击时再解析 URL / 拉取资源”。如果这些资源只是演示素材,优先改成外链/CDN。 |
| 167 | +- 对 `trailer.mp4` 改成更低码率版本,至少补一份 `webm` 或更低分辨率资源。若只是展示页背景视频,优先提供 poster,滚动到可视区域或用户点击后再加载。 |
| 168 | +- 将 `spring.png`、`he.png`、`song.png`、`xue.png` 转成 `webp/avif`,并按展示尺寸重新导出。它们目前在首页、Demo、Tilt、FeatureAny、AutoSlider 等多个位置复用,体积收益会立刻体现。 |
| 169 | + |
| 170 | +### 优先级 P1:减少默认路径上的重功能 |
| 171 | + |
| 172 | +- 将首页里同步引入的 `InteractiveBook` 改成真正的动态加载,避免默认构建始终产出并暴露 1 MiB 的 PDF worker。 |
| 173 | +- 将 `ChatGpt` 页里的 Mermaid 能力再拆一层:只有检测到 Mermaid 代码块或用户打开 Mermaid 面板时再加载 Mermaid。当前虽然 Mermaid 已是独立 chunk,但菜单预加载会放大实际下载成本。 |
| 174 | +- 评估 `src/pages/layout/proSecNav/index.jsx` 的 hover 预加载策略,至少把 `ChatGpt`、`Echarts`、`ReactMusic`、`MyVideo`、`BigScreen` 这类重页面从自动预取名单里拿掉。 |
| 175 | + |
| 176 | +### 优先级 P2:收缩第三方库体积 |
| 177 | + |
| 178 | +- `echarts` 改成按需注册方式,不再使用全量入口。目标是只引入当前图表页实际使用的 chart、component、renderer。 |
| 179 | +- `lodash` 当前进入 `vendor` 的是整包 `lodash/lodash.js`。优先替换为按方法导入,或迁移到 `lodash-es` 并交给 tree-shaking。 |
| 180 | +- `hls.js` 已经被拆成独立 chunk,方向基本正确。后续只需避免非 HLS 场景触发预加载即可。 |
| 181 | + |
| 182 | +## 建议的落地顺序 |
| 183 | + |
| 184 | +1. 先处理本地音频与视频资源。 |
| 185 | +2. 再把首页 `InteractiveBook` 改成动态加载。 |
| 186 | +3. 再缩减菜单 hover 预加载名单。 |
| 187 | +4. 最后做 `echarts` 与 `lodash` 的代码级瘦身。 |
| 188 | + |
| 189 | +## 依赖回退说明:filemanager-webpack-plugin 10.0.0 |
| 190 | + |
| 191 | +### 结论 |
| 192 | + |
| 193 | +- 当前仓库应保持 `filemanager-webpack-plugin` 为 `^9.0.1`。 |
| 194 | +- 不要升级到 `10.0.0`,除非上游重新发布修复版本并验证通过。 |
| 195 | + |
| 196 | +### 回退原因 |
| 197 | + |
| 198 | +- 本项目的 Webpack 生产配置文件 `webpack/webpack.prod.js` 是 ESM。 |
| 199 | +- `filemanager-webpack-plugin@10.0.0` 的 npm 发布包中实际包含的是 `dist/index.mjs`,但其 `package.json` 却将 `import`/`module` 入口声明为 `dist/index.js`。 |
| 200 | +- 结果是:Webpack CLI 在加载 ESM 配置时会直接报错,无法解析该插件入口。 |
| 201 | + |
| 202 | +典型报错如下: |
| 203 | + |
| 204 | +```text |
| 205 | +Error [ERR_MODULE_NOT_FOUND]: Cannot find module '.../node_modules/filemanager-webpack-plugin/dist/index.js' |
| 206 | +Did you mean to import "filemanager-webpack-plugin/dist/index.cjs"? |
| 207 | +``` |
| 208 | + |
| 209 | +### 为什么回退到 9.0.1 |
| 210 | + |
| 211 | +- `9.0.1` 的发布包同时包含 `dist/index.js` 与 `dist/index.cjs`,其包元数据与实际产物一致。 |
| 212 | +- 在该版本下,`webpack/webpack.prod.js` 可以继续使用标准 ESM 写法: |
| 213 | + |
| 214 | +```javascript |
| 215 | +import FileManagerPlugin from 'filemanager-webpack-plugin' |
| 216 | +``` |
| 217 | + |
| 218 | +### 升级前检查建议 |
| 219 | + |
| 220 | +如果后续需要重新评估升级,请先确认两点: |
| 221 | + |
| 222 | +1. `npm pack filemanager-webpack-plugin@<version>` 解包后,ESM 入口文件是否真实存在。 |
| 223 | +2. `SKIP_OPTIMIZE_MEDIA=1 npm run build:production` 是否可以无兼容补丁直接通过。 |
| 224 | + |
0 commit comments