fix: 发版后懒加载 chunk 失效白屏——ErrorBoundary 自动刷新 + lazy 重试 #1732
Reference in New Issue
Block a user
Delete Branch "fix/chunk-load-white-screen"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
背景
所有页面 React Router lazy 动态 import。发版后旧 chunk 文件名被删除,停留在旧标签页的用户点菜单时 import 404(
Failed to fetch dynamically imported module/ ChunkLoadError),无任何兜底,整页白屏。改动(apps/web)
1. 全局 ErrorBoundary 捕获 chunk 失效自动恢复
utils/chunkLoadError.ts:识别 chunk 加载错误(Vite / webpack / 字符串多形态);sessionStorage 标记最近 10min 内是否已为 chunk 失效自动刷新过(防刷新死循环,标记 TTL 10min 过期后允许再次自愈)components/common/ChunkErrorBoundary.tsx:包裹 RouterProviderwindow.location.reload()(刷新后 index.html 是 no-cache 的,拿到新 chunk 引用,白屏自愈)2. 路由 lazy 加载失败重试
router/lazyRoute.ts:包一层自动重试(最多 2 次,300/800ms),网络抖动/瞬态失败无感恢复;chunk 404 重试仍失败(旧文件名已不存在)则抛出交给 Boundary;非 chunk 错误立即抛出不浪费重试appRoutes.tsx:28 个路由 lazy 统一替换为lazyRoute3. nginx 缓存策略(经核实已满足,未改动)
infra/docker/nginx.conf现状:location = /index.html已是no-cache, no-store, must-revalidate(且try_files ... /index.html的内部跳转匹配该 location),/assets/*静态资源expires 1y + immutable。符合「index.html 每次校验、hash 资源长缓存」要求,无需改动。部署后会实测响应头确认。测试
🚀 预览环境已部署
CI全绿,自动审批通过。
CI全绿,自动审批通过。
【阻塞级判定】
📊 审查概览
🔴 阻塞级问题(必须修复)
safeStorage.setItem在捕获异常时会静默失败(不抛错),而reloadForChunkError无论setItem是否成功都会执行window.location.reload()。在 Safari 无痕模式或禁用 Cookie/Storage 的严格环境下,sessionStorage操作会抛出异常。此时getChunkReloadedAt因读取失败返回null,ChunkErrorBoundary判断为未刷新过,于是调用reloadForChunkError。由于无法写入标记,页面刷新后再次进入相同逻辑,导致浏览器陷入“检测到更新 -> 刷新 -> 检测到更新”的死循环,直到浏览器拦截。?chunk_reload_ts=xxx)作为降级标记,或者修改reloadForChunkError逻辑,仅在确认标记写入成功后才刷新;若写入失败,应视为无法自动恢复,直接抛出错误或返回状态让 ErrorBoundary 展示手动恢复界面。💡 改进建议(不阻塞合并)
goHomeRecover函数中使用window.location.href = "/"强制跳转根路径。如果应用部署在子路径(如example.com/my-app),此跳转会将用户带离应用域或导致 404。建议结合window.location.origin和应用的basename配置,或者使用 React Router 的navigate(如果可注入)进行相对路径跳转。✅ 良好实践
safeStorage封装了 sessionStorage 操作,考虑了异常捕获的意识(虽然逻辑需完善)。lazyRoute实现了自动重试机制,能有效区分网络抖动和真正的版本更新导致的 Chunk 失效。✅ 格式检查通过 | ❌ 逻辑审查需修改 | ⚠️ 建议关注性能
🤖 由 AI 代码审查机器人自动生成 | 2026-09-06 05:34:53 | 模型:
🗑️ 预览环境已清理
PR #1732 已关闭或合并,对应的预览环境已被清理。