# 实现方案 — 2026-04-16-20-33-12 ## 根因分析 `autoCaptureFrames` 的 `for` 循环内部,自动插入逻辑使用了: ```tsx if ((settings.autoInsertDelay || 0) > 0) { await new Promise(r => setTimeout(r, (settings.autoInsertDelay || 0) * 1000)); } ``` `await` 会暂停整个 `for` 循环的执行,导致: 1. 关键帧摘取被强制暂停,等待延迟结束; 2. 所有帧必须一张一张串行处理,整体耗时 = 摘取时间 + 插入延迟 × 插入帧数; 3. 用户体验上感觉"卡顿"或"慢"。 ## 修改文件清单 | 文件 | 修改类型 | 说明 | |------|---------|------| | `src/pages/ReportEditor.tsx` | 修改 | `autoCaptureFrames` 中自动插入逻辑改为 `setTimeout` 非阻塞执行 | ## 具体代码变更 ### 变更:`autoCaptureFrames` 中的插入逻辑(约第 523-535 行) **当前代码:** ```tsx if (settings.autoInsertFrames && settings.autoInsertFrameIndices?.includes(i) && editorRef.current) { if ((settings.autoInsertDelay || 0) > 0) { await new Promise(r => setTimeout(r, (settings.autoInsertDelay || 0) * 1000)); } const emptyPlaceholder = editorRef.current.querySelector('.image-placeholder:not(.has-image)') as HTMLElement | null; if (emptyPlaceholder) { emptyPlaceholder.innerHTML = `...`; emptyPlaceholder.classList.add('has-image'); } } ``` **修改为:** ```tsx if (settings.autoInsertFrames && settings.autoInsertFrameIndices?.includes(i)) { const baseDelay = (settings.autoInsertDelay || 0) * 1000; const insertOrderIndex = settings.autoInsertFrameIndices.indexOf(i); const actualDelay = baseDelay > 0 ? baseDelay * (insertOrderIndex + 1) : 0; setTimeout(() => { if (!editorRef.current) return; const emptyPlaceholder = editorRef.current.querySelector('.image-placeholder:not(.has-image)') as HTMLElement | null; if (emptyPlaceholder) { emptyPlaceholder.innerHTML = ` × `; emptyPlaceholder.classList.add('has-image'); contentRef.current = editorRef.current.innerHTML; saveDraftToStorage(); } }, actualDelay); } ``` **效果:** - `for` 循环全速运行,不再被插入延迟阻塞; - 每张需要插入的帧按顺序延迟(第 1 张 delay,第 2 张 2×delay...),避免同时插入; - `setTimeout` 回调中实时查询 DOM 获取最新的空 placeholder; - 插入后同步 `contentRef.current` 并保存草稿。 ### 附加变更:移除循环后的批量 `contentRef` 更新 当前代码在循环结束后: ```tsx if (settings.autoInsertFrames && editorRef.current) { contentRef.current = editorRef.current.innerHTML; } ``` 由于每个 `setTimeout` 回调内部已经单独更新 `contentRef` 和保存草稿,且循环结束时可能 `setTimeout` 尚未执行,这句批量更新既不及时也可能遗漏。建议**移除或保留不影响功能**。为简化逻辑,选择保留但无实质影响,因为非阻塞的 `setTimeout` 回调会各自负责自己的保存。 ## 风险点 | 风险 | 级别 | 应对措施 | |------|------|---------| | `setTimeout` 回调执行时 placeholder 已被用户手动填充 | 低 | 回调中实时查询 `.image-placeholder:not(.has-image)`,找不到则跳过,不会覆盖用户内容 | | 多张图片按顺序延迟插入时,用户快速离开页面 | 低 | 每次插入后都调用 `saveDraftToStorage()`,已插入的图片会被保存;未执行的 `setTimeout` 自然丢弃 | ## 回滚策略 修改范围极小,仅涉及 `autoCaptureFrames` 中的几行代码。如有异常可直接 revert。