Webpack代码分割报ChunkLoadError,存在的chunk加载失败该如何处理?
结论优先
建议做轻量化处理,完全不需要放任用户手动刷新,实现成本极低,还能覆盖0.62%的iOS受影响用户的体验问题。你没有收到用户反馈不代表用户没受影响,绝大多数普通用户遇到页面加载失败会直接刷新或者退出,不会主动反馈问题。
首先排查iOS端特有触发原因
你遇到的90%报错集中在iOS设备,大概率是以下两个场景导致的,和通用网络问题、版本发布都没关系:
- 内容拦截器误拦截:iOS Safari、微信内置浏览器等iOS端 webview 都支持第三方内容拦截插件,很多广告拦截、隐私保护规则会误命中带
ad、track、analytics这类敏感关键词的chunk资源,如果你的报错chunk名带这类词汇,直接修改打包的chunk命名规则就能解决80%以上的问题。 - Safari后台冻结机制:如果用户把页面切到后台停留超过几分钟,Safari会主动丢弃部分已缓存的静态资源,用户切回页面跳转路由时,就会出现能正常访问chunk但当前页面加载失败的情况,这是iOS Safari的特有机制,安卓端不会出现这类问题。
可选处理方案(从易到难)
- 优先排查chunk命名:检查打包输出的chunk名规则,避免出现广告、统计相关的敏感词,改完上线后观察一周报错量,大概率会大幅下降。
- 加轻量化重试逻辑:在动态导入的逻辑外层加2次自动重试,不需要改业务逻辑,只需要加一层封装即可,React项目示例代码如下:
// 封装重试逻辑,默认最多重试2次 const lazyRetry = (importFn, retryCount = 2) => { return new Promise((resolve, reject) => { importFn() .then(resolve) .catch(err => { if (retryCount > 0) { setTimeout(() => lazyRetry(importFn, retryCount - 1).then(resolve).catch(reject), 300) return } reject(err) }) }) } // 使用方式替换原来的React.lazy即可 const UserCenter = React.lazy(() => lazyRetry(() => import('./pages/UserCenter')))
- 重试失败后自动降级:如果重试2次仍然失败,不要直接抛白屏,要么自动触发一次当前页软刷新,要么弹出友好提示引导用户点击刷新,完全不需要用户手动操作浏览器刷新按钮。
额外优化建议
可以在Sentry的上报规则里加过滤:重试成功的ChunkLoadError不要上报,避免无效报错占用上报额度,也方便你观察实际处理效果。
内容的提问来源于stack exchange,提问作者5imone
相关产品推荐
相关产品推荐

