第 11 章 项目最佳实践与进阶

发布时间:2026/10/21 2:27:02
第 11 章 项目最佳实践与进阶
本章目标总结项目中的设计模式和最佳实践帮你把知识系统化⭐⭐⭐⭐ 难度进阶 | ⏱️ 预计时间1.5 小时11.1 项目中用到的设计模式设计模式不是「八股文」而是解决特定问题的「套路」。这个项目里用到了很多经典的设计模式我们来盘点一下。门面模式Facade Pattern是什么对外提供一个统一的大接口内部封装复杂的子系统。用在哪里网关层Gateway上层代码 │ ▼ ┌─────────────┐ │ Gateway │ ← 统一的大接口 │ getAgents │ │ sendMessage│ │... │ └──────┬──────┘ │ ┌────┴────┐ ▼ ▼ HTTP WS为什么好上层不用关心底层是 HTTP 还是 WS换底层实现不影响上层所有数据格式转换集中在网关层做工厂模式Factory Pattern是什么用一个工厂函数/类来创建对象调用者不用知道具体实现。用在哪里createGateway()工厂函数functioncreateGateway():WorkbenchGateway{if(useMock)returnnewMockGateway();returnnewHttpGateway();}为什么好创建逻辑集中要改只改一个地方调用者只依赖接口不依赖具体类方便加新的实现观察者模式Observer Pattern是什么一个对象变化了通知所有订阅了它的对象。用在哪里MobX 的 observable reaction、WebSocket 的事件监听observable 数据变了 │ ▼ 所有用到它的组件自动更新为什么好数据和视图解耦不用手动调「刷新」方法细粒度更新性能好策略模式Strategy Pattern是什么定义一族算法把每个算法封装起来使它们可以互相替换。用在哪里双 WS 通道策略chat / work-orderfunctiongetPrimaryWs(){if(transportchat)returnchatWs;returnworkOrderWs;}为什么好新增策略不用改原有逻辑运行时可以动态切换每个策略独立互不干扰状态模式State Pattern是什么对象的行为取决于它的状态状态变了行为也变。用在哪里消息生命周期pending → sending → sent / error、流式回复阶段用户消息的状态 pending → sending → sent ↘ error为什么好状态转换逻辑清晰每个状态下能干什么不能干什么一目了然避免「这个状态下居然能点这个按钮」的 bug备忘录模式Memento Pattern是什么保存对象的状态以后可以恢复。用在哪里执行日志缓存切换会话时恢复最后一次的执行面板// 缓存runCache.set(runId,events);// 恢复eventsrunCache.get(runId);为什么好用户切换回来时之前的状态还在不用每次都重新加载体验更连贯11.2 MobX 使用最佳实践✅ 推荐做法1. 用makeAutoObservable最省事、最不容易出错。99% 的场景用它就够了。classStore{count0;constructor(){makeAutoObservable(this);// 自动识别}}2. 细粒度 observable数据拆分细一点更新的时候只有变化的部分触发渲染。// ✅ 好每个消息独立改一个只重渲染一个messages:Message[][];// ❌ 不好整个对象替换所有消息都重渲染setMessages(newMessages);3. 多用 computed能从现有数据算出来的就用 computed不要手动维护。// ✅ 好自动计算、自动缓存getcompletedCount(){returnthis.todos.filter(tt.done).length;}// ❌ 不好每次改 todos 都要手动更新这个数completedCount0;4. 异步操作包 runInAction异步回调里改状态用runInAction包一下。asyncloadData(){constdataawaitapi.fetch();runInAction((){this.datadata;this.loadingfalse;});}❌ 避免的做法1. 不要在组件里直接改 observable// ❌ 不好业务逻辑散落在组件里 button onClick{() store.count} // ✅ 好通过 action 方法改 button onClick{() store.increment()}2. 不要把所有东西塞一个 Store一个 Store 超过 500 行就要考虑拆分了。3. 不要滥用 reaction/autorun大部分场景用computedobserver就够了。reaction 是应急手段不是常规武器。11.3 实时通信最佳实践WebSocket 必做的 5 件事功能为什么要做怎么做自动重连网络波动是常态不能断了就断了指数退避最多 N 次心跳保活检测连接是不是假死定时发 ping超时就断了重连消息队列连接没建立好的时候发的消息不能丢存队列里连上再发重连后同步断连期间的消息要补上重连后拉取最新状态错误提示断了要告诉用户Toast 提示 重连中状态流式回复的经验1. 本地回显一定要做发完消息立即显示别等后端返回。慢个 100ms 体验差很多。2. 始终以最终内容为准流式增量可能会有误差比如后端做了修改end 事件里的最终内容才是准的。// delta 阶段追加appendAssistantDelta(messageId,delta);// end 阶段以最终内容为准setAssistantFinalContent(messageId,finalContent);3. 后台会话不渲染用户没在看的会话只更新未读数不加载消息内容。不然几十上百个会话一起流式更新页面会卡。if(currentConversationId!event.conversationId){// 后台会话只标记未读markUnread(event.conversationId);return;}// 前台会话更新消息appendMessage(event.message);11.4 组件设计最佳实践容器组件 vs 展示组件类型职责接触什么容器组件数据获取、业务逻辑Store、网关展示组件只负责渲染和交互Props、本地 state// 容器组件管数据 const MessageListContainer observer(() { const { sessionStore } useStore(); return MessageList messages{sessionStore.messages} /; }); // 展示组件只管渲染 function MessageList({ messages }) { return messages.map(msg MessageBubble msg{msg} /); }小贴士小项目不用分这么细但大项目分清楚了维护起来省心。组件粒度怎么把握情况建议一个组件超过 400 行考虑拆分子组件一段 JSX 有自己的逻辑和状态拆成独立组件两个地方用到了同样的 UI抽成公共组件拆了之后 props 要传七八个可能拆太细了合回去一句话拆到「每个组件做一件事而且名字能准确描述它做什么」就差不多了。优先复用 UI 库组件能用 Ant Design 的组件就别自己写按钮、弹窗、表单、表格… 直接用样式不满足用 className 覆盖或 theme 定制功能不满足先看看 Pro 组件有没有自己写一个「看起来差不多」的组件后期维护成本很高。11.5 性能优化要点前端性能优化的优先级先做见效快的再做费力的。优先级优化手段难度收益 高后台会话不渲染消息低高 高代码分割 按需加载中高 中MobX 细粒度更新低中 中长列表虚拟滚动中中 低图片懒加载低低 低防抖节流低低本项目的关键优化点1. 流式消息的性能流式消息是最频繁的更新场景一定要优化好每条消息独立的 observable改一条只重渲染一条用observer包裹消息项组件避免在消息渲染里做复杂计算2. 切换会话的性能切换会话是常见操作切换时清空旧会话的大对象防止内存泄漏执行日志按 run 缓存不要全量存图片和文件预览懒加载3. 首屏加载性能重组件代码编辑器、文件预览动态 import路由懒加载字体和图标按需加载11.6 代码质量保障规范三件套工具管什么怎么用Prettier格式缩进、引号、换行保存时自动格式化ESLint代码质量变量用没用到、潜在 bug提交前检查TypeScript类型安全写代码的时候就有提示经验Prettier 管「长什么样」ESLint 管「写得对不对」TypeScript 管「类型对不对」。三者配合代码质量有基本保障。测试策略测试类型测什么优先级单元测试工具函数、Store 逻辑高组件测试组件渲染和交互中E2E 测试完整流程走一遍低成本高建议核心逻辑Store、工具函数一定要有单测。UI 组件可以少写点因为 UI 变化快测试维护成本高。Code Review 重点有没有越级调用比如组件直接调 axios数据改对了吗有没有竞态条件、状态不一致边界情况处理了吗空数据、加载中、错误态命名清晰吗变量名、函数名能不能看懂有没有重复代码能不能抽成公共的11.7 学习路线建议学完这个教程之后怎么继续提升阶段一打基础1-2 个月React Hooks 深入理解useEffect、useMemo、useCallbackTypeScript 高级类型泛型、条件类型、映射类型MobX 官方文档通读一遍阶段二提能力2-4 个月学一个状态管理库Redux / Zustand和 MobX 对比着学学 WebSocket 和 SSE 的原理和区别学 React 性能优化memo、useMemo、虚拟列表做一个完整的项目练手阶段三进阶级4-6 个月微前端架构低代码 / 可视化搭建前端工程化构建原理、CI/CDNode.js 全栈开发学习心得别光看要动手。跟着做一遍比看十遍都管用。遇到问题先自己想、自己查实在解决不了再问别人。11.8 全书总结恭喜你学完了整个教程我们从项目概述开始一路走过了架构设计五层架构工程化Vite、Less、ESLint状态管理MobX、根 Store 子 Store网关层统一通信抽象实时通信WebSocket、流式回复聊天模块消息列表、输入框执行面板工具调用展示审批机制安全保障更多业务模块定时任务、记忆、设置…三句最重要的话分层解耦——每一层只管自己的事上层不操心下层怎么实现实时优先——AI 产品的核心体验是「实时感」所有设计围绕这个展开观测并重——不仅能指挥 AI 干活还要能看清它干了啥、为什么这么干送给你的话做项目就像搭积木——先搭骨架架构再填血肉业务模块最后打磨细节体验优化。一开始不用追求完美先跑起来再慢慢迭代。每一个优秀的项目都是从一个「能跑的简陋版本」开始的。加油你可以的感谢阅读本教程。如果觉得有帮助记得动手实践——代码是写出来的不是看出来的。