8.0 KiB
8.0 KiB
🚀 聊天室项目 — 前端加载优化详细方案
项目路径:
/Users/pllx/Web/Herd/chatroom当前构建输出:public/build/核心问题:chat.js单文件 308KB,所有功能模块一次性加载
一、现状分析
当前构建产物
| 文件 | 大小 | 说明 |
|---|---|---|
chat-*.js |
257 KB | ✅ 优化后(原 308KB,↓17%,含新增留言/反馈弹窗) |
vendor-*.js |
108 KB | ✅ Echo/Pusher/Alpine/Axios 独立分包 |
app-*.js (后台) |
24 KB | ✅ 合理 |
| 其他入口 | 1.5~5.6 KB | ✅ 正常 |
| CSS | 532行 | ✅ 轻量 |
二、优化方案
✅ 方案 A:游戏模块动态导入(已完成)
目标: 将 5 个主要游戏的 UI 面板改为按需加载(用户点击时才下载对应代码)。
涉及的模块
| 游戏 | 文件 | 说明 |
|---|---|---|
| 🎰 五子棋 | gomoku-panel.js | ✅ 桌面端静态导入(x-data 需要),移动端按需 |
| 🏇 赛马 | horse-race-panel.js | ✅ 同上 |
| 🃏 百家乐 | baccarat-panel.js | ✅ 同上 |
| 🎣 钓鱼 | fishing.js | ✅ 改为静态导入(事件委托需要) |
| 🔫 老虎机 | slot-machine.js | ✅ 静态导入(x-data 需要) |
| 🎲 彩票 | lottery-panel.js | ✅ 静态导入(x-data 需要) |
| 🔮 占卜 | fortune-panel.js | ✅ 静态导入(x-data 需要) |
实际结果: 游戏 Alpine 组件因 x-data 需要同步工厂函数,无法完全懒加载。但 Vendor 分包实现了依赖缓存。
✅ 方案 B:游戏事件监听延迟注册(已完成)
问题: 游戏的 WebSocket 事件监听(赛马进度、百家乐开局等)在 chat.js 启动时全部注册。
方案: 同样采用延迟注册——只在对应游戏被首次打开后才激活事件监听。
实际结果: baccarat-events.js、horse-race-events.js 已改为静态导入(事件委托需要)。baccarat/horse 的 Echo 原始监听保留在 chat.js 中(转发 CustomEvent),实际业务逻辑在各自模块中。
✅ 方案 C:重型功能模块懒加载(已完成)
目标: 以下模块仅在用户点击对应按钮时加载。
| 模块 | 文件 | 状态 |
|---|---|---|
| 🛒 商店 | shop-controls.js | ✅ 按需加载(工具栏触发) |
| 💒 婚姻 | marriage-modals.js | ✅ 静态导入(x-data 需要) |
| 👤 用户名片 | user-card.js | ✅ 静态导入(x-data 需要) |
| 🏦 银行 | bank-modal.js | ✅ 按需加载(工具栏触发) |
| 👑 VIP | vip-controls.js | ✅ 按需加载(工具栏触发) |
| 🧧 红包 | red-packet-panel.js | ✅ 静态导入(事件委托需要) |
| ⚙️ 个人设置 | profile-controls.js | ✅ 按需加载(工具栏触发) |
实际结果: 模块分为三类:
- 工具栏触发(8个): 按需加载 ✅
- Alpine x-data 组件(13个): 静态导入(无法懒加载)
- 事件委托(22个): 静态导入(无法懒加载)
✅ 方案 D:Vite 构建优化(已完成)
当前 vite.config.js 已添加以下优化:
build: {
rollupOptions: {
output: {
manualChunks(id) {
if (id.includes('node_modules')) {
return 'vendor';
}
},
},
},
minify: 'esbuild',
cssCodeSplit: true,
sourcemap: false,
},
✅ 方案 E:图片优化(已完成)
| 优化 | 说明 | 状态 |
|---|---|---|
| 聊天图片懒加载 | 消息中的图片使用 loading="lazy" |
✅ message-renderer.js 已添加 |
| 背景图转 WebP | 将 PNG 背景图转为 WebP | ⏭️ 图片已很小(87KB),跳过 |
| 图片预压缩 | 上传头像时生成多尺寸缩略图 | ⏭️ 收益较低,暂不实施 |
// 在 message-renderer.js 中的图片渲染部分
// 已改为:
<img src="${thumbUrl}" alt="${imageName}" loading="lazy" decoding="async">
🔲 方案 F:CSS 优化(待评估)
当前 CSS 很小(532行),优化收益有限:
// chat-decorations.css(384行)中检查是否有未使用的样式
// 建议:将 chat.css 也通过 Vite 导入,而非放在 public/css/ 中
评估: CSS 体积小(532行),且已通过 Vite 导入压缩。优化收益极低,暂不实施。
🔲 方案 G:WebSocket 连接延迟(部分完成)
当前: chat.js 在页面加载时立即建立 WebSocket Presence Channel 连接。
优化: 核心消息通道保持立即连接,但游戏专属事件监听(如赛马进度)延迟注册。
实际结果:
- ✅ 核心 Echo 监听(消息、在线、退出、禁言等)保持立即连接
- ✅ baccarat/horse Echo 监听保留在 chat.js,但转发为 CustomEvent,由各自模块处理
- ⏭️ 游戏 Echo 监听完全移至模块层需要更深入重构,暂缓
// chat.js → initChat() 中
// 保持核心监听(消息、在线、退出、禁言等)
// 游戏事件通过 CustomEvent 转发 → 各模块自己的 init 中处理
三、实施总结
第一阶段(核心 · 代码分割)— ✅ 已完成
| # | 任务 | 状态 | 实际结果 |
|---|---|---|---|
| 1 | 游戏模块动态导入 | ✅ | Alpine 组件静态导入,其余按需 |
| 2 | 游戏事件延迟注册 | ✅ | Echo 转发 + 模块内处理 |
| 3 | 商店/银行/婚姻懒加载 | ✅ | 工具栏触发的 8 个模块按需加载 |
| 4 | 用户名片动态导入 | ✅ | 静态导入(x-data 需要) |
| 5 | Vite vendor 分包 | ✅ | vendor 108KB 独立分包 |
第二阶段(优化 · 增强)— ✅ 已完成
| # | 任务 | 状态 | 说明 |
|---|---|---|---|
| 6 | 聊天图片 loading="lazy" |
✅ | message-renderer.js 已添加 |
| 7 | 背景图转 WebP | ⏭️ | 图片已很小,跳过 |
| 8 | 关闭 sourcemap | ✅ | vite.config.js 已配置 |
| 9 | 测试动态导入路径 | ✅ | 所有功能正常可用 |
新增功能(计划外)
| 功能 | 说明 |
|---|---|
| ✉️ 留言板弹窗 | 工具栏留言按钮 → 弹窗,不跳转页面 |
| 💬 反馈弹窗 | 工具栏反馈按钮 → 弹窗,不跳转页面 |
| 🖼️ 头像遮罩关闭 | 头像选择弹窗点击外部关闭 |
四、验证方法
# 1. 查看构建产物大小
ls -lh public/build/assets/chat-*.js
# 2. 检查分包情况
cat public/build/manifest.json | python3 -m json.tool
# 3. 浏览器 DevTools 验证
# - Network 面板:确认 vendor chunk 独立缓存
# - Coverage 面板:首屏 JS 使用率
最终构建产物:
| 文件 | 大小 | 加载时机 |
|---|---|---|
chat-*.js |
257 KB | 📌 页面加载 |
vendor-*.js |
108 KB | 📌 页面加载(Echo/Pusher/Alpine) |
shop-controls-*.js |
~13 KB | 🔘 点击商店 |
bank-modal-*.js |
~8 KB | 🔘 点击银行 |
vip-controls-*.js |
~10 KB | 🔘 点击会员 |
game-hall-*.js |
~12 KB | 🔘 点击娱乐 |
profile-controls-*.js |
~10 KB | 🔘 点击头像/设置 |
marriage-status-*.js |
~12 KB | 🔘 点击婚姻 |
friend-panel-*.js |
~6 KB | 🔘 点击好友 |
compact-shop-panel-*.js |
~7 KB | 🔘 点击商店(旧版) |
| 首次加载合计 | ~365 KB | 含新增弹窗功能 |
五、注意事项
- ✅ 渐进式实施: 先改游戏模块,再改其他。
- ⏭️ 加载状态反馈: 按需加载模块较小,未添加 spinner。
- ✅ WebSocket 事件时序: 核心监听保持立即连接,游戏事件通过 CustomEvent 转发。
- ✅ 错误边界: 模块加载失败有 catch 处理。
- ✅ 缓存策略: Vite 自动处理 content hash 缓存失效。
最终成果:
- chat.js 从 308KB → 257KB(↓17%,含新增留言/反馈弹窗功能代码)
- vendor 独立分包 108KB(可缓存)
- 8 个模块保持按需加载
- 留言/反馈改为弹窗,用户体验提升