主题
React 性能优化
React 代码分割、lazy 和 Suspense 如何配合优化首屏?
代码分割的目标是减少关键路径 JavaScript,但拆分过度也可能增加请求、等待和交互延迟。
面试官想考什么
- 什么内容适合懒加载? 考察关键路径判断。
- Suspense fallback 如何设计? 考察用户体验。
- 动态 chunk 加载失败怎么办? 考察稳定性。
- 为什么拆包后反而变慢? 考察网络和缓存取舍。
一句话回答
text
把低概率、非首屏或重依赖功能按路由和交互边界分割,用 lazy 加载并用 Suspense 表达等待,同时通过预取、缓存和 chunk 失败重试控制额外延迟。面试回答详解
1. 分割目标
text
首屏关键代码 -> 同步加载
低概率路由/编辑器/图表/地图 -> 动态加载
高概率下一步 -> 空闲或 hover 预取2. Suspense 边界
边界应放在用户能理解的独立区域,fallback 尺寸尽量稳定,避免整页闪烁和布局跳动。错误边界要和 Suspense 配合,处理 chunk 404、网络失败和版本不一致。
3. 拆分取舍
拆分减少初始 JS,但会带来额外请求、解析时机和交互等待。低缓存命中、弱网或频繁访问的功能不能只看首包大小,要同时看后续交互延迟。
4. 验证
用 bundle analyzer、Network、Coverage、LCP、INP 和 RUM 验证;检查是否存在重复依赖、过大的 Client Component 或 chunk 预取过度。
可直接背诵的 30 秒回答
text
我会按路由、交互和使用概率做代码分割,把非首屏的图表、编辑器和管理功能动态加载。Suspense 只包住独立的等待区域,fallback 要稳定,错误边界处理 chunk 加载失败。拆分后不只看首包,还要看请求数、缓存命中、LCP、后续交互延迟和弱网体验。扩展知识
加载决策
text
关键且高概率 -> 首屏
非关键且低概率 -> lazy
高概率下一步 -> prefetch
失败 -> error boundary + retry/fallback面试官追问链
追问一:lazy 加载失败后刷新页面有用吗?
- 考察点:是否考虑版本和网络问题。
- 回答方向:可能有用,但要避免无限刷新;记录 release,先重试一次,再提供刷新、降级或返回入口。
追问二:Suspense 会自动把所有异步请求并行吗?
- 考察点:是否避免误解。
- 回答方向:不会。它表达挂起和边界,数据依赖是否并行仍取决于请求设计和框架运行时。
追问三:如何选择拆分粒度?
- 考察点:性能和复杂度取舍。
- 回答方向:按关键路径、访问概率、依赖体积、缓存复用和交互等待选择,不追求 chunk 数量越多越好。