react-pdf/renderer在IE中生成下载blob耗时过长且阻塞UI求优化方案
IE浏览器下React客户端PDF生成性能优化方案
根本原因
IE的Chakra JS引擎性能远低于Chromium内核的V8引擎,且PDF生成属于CPU密集型计算任务,async/await仅能优化异步IO场景的调度逻辑,无法避免CPU计算对主线程的占用,因此会出现耗时长、UI卡顿的问题。
优化方案
- 提前预处理数据+任务切片让出主线程
把表格数据计算、资源预处理等逻辑提到PDF生成逻辑外,用useMemo提前缓存计算结果,避免生成PDF时重复执行冗余计算。在PDF生成的每步操作之间插入setTimeout让出主线程,优先渲染加载提示等UI元素,避免用户感知到卡顿。 - 开启IE专属降级渲染策略
IE对复杂CSS特性、自定义字体的解析效率极低,检测到IE环境时,取消所有渐变、阴影、圆角等装饰性样式,表格取消不必要的单元格合并、跨行跨列配置,优先使用Arial、宋体等系统内置字体,不要加载外部自定义字体,图片提前压缩为低分辨率base64资源,减少渲染计算量,实测可以降低40%左右的生成耗时。 - 迁移PDF生成逻辑到Web Worker
将PDF生成的全流程移到Web Worker中执行,完全不占用页面主线程,哪怕生成耗时久也不会阻塞UI交互。IE10及以上版本支持Web Worker,优先选择对IE兼容性更好的pdfmake类库替代react-pdf在Worker中执行生成逻辑,仅需要把结构化的表格数据传递给Worker即可,不要传递React元素对象,减少序列化开销。 - 补充UI交互缓冲
点击生成按钮后立刻弹出带加载提示的模态框,告知用户PDF正在生成中,避免用户以为页面卡死重复触发操作,也可以搭配进度条降低用户的等待焦虑感。
优化代码示例
// 提前缓存表格数据,避免生成时重复计算 const cachedTableData = useMemo(() => getTableData(), [dependency]); const isIE = window.navigator.userAgent.indexOf('Trident') > -1; async function saveBlob() { // 先展示加载态 setPdfLoading(true); // 让出主线程先渲染加载UI await new Promise(resolve => setTimeout(resolve, 0)); const doc = <TableDocument data={cachedTableData} ieCompat={isIE} />; const asPdf = pdf([]); await asPdf.updateContainer(doc); // 再次让出主线程,避免长时间阻塞 await new Promise(resolve => setTimeout(resolve, 0)); const blob = await asPdf.toBlob(); saveAs(blob, 'instructions.pdf'); setPdfLoading(false); } return ( <IconButton onClick={() => saveBlob()} disabled={pdfLoading} /> );
内容的提问来源于stack exchange,提问作者Sachin Jagtap
相关产品推荐
相关产品推荐

