Generator 可实现分批渐进式渲染,通过将大数据拆分为小批次并配合 requestIdleCallback 或 requestAnimationFrame 逐步执行,避免主线程阻塞;其天然可中断特性支持暂停、恢复、中断与低内存占用,结合 Canvas/SVG 增量绘制及可视区优化,保障交互流畅性。

Generator 可以在复杂数据可视化中实现分批渐进式渲染,核心在于把“一次性生成全部 DOM/Canvas 元素”拆成可控的、带暂停能力的小批次任务,配合浏览器空闲时间(如 requestIdleCallback)或帧节奏(requestAnimationFrame)逐步执行,避免主线程长时间阻塞导致页面卡顿或失去响应。
用 Generator 拆解大数据渲染任务
面对数万级节点的力导向图、时间序列密集折线或地理热力瓦片,直接遍历绘制会触发长任务(>50ms),引发掉帧。Generator 提供天然的“可中断迭代器”能力:
- 把原始数据按逻辑分块(如每 200 个点一组),yield 每一块的渲染指令或数据子集
- 每次调用
iterator.next()只处理一块,返回 { value, done },控制权交还给调度器 - 不预先展开全部数据,内存占用低,且可随时中止或跳转
与 requestIdleCallback 协同实现用户感知流畅
利用浏览器空闲时间执行渲染,确保高优先级交互(如拖拽、缩放)不被抢占:
- 创建 Generator 函数,接收数据和批次大小,yield 每批待渲染的数据片段
- 在
requestIdleCallback回调中调用next(),若未完成则继续注册下一次回调 - 设置 timeout 防止空闲时间过长导致渲染延迟,也可降级为
setTimeout(..., 0)
function* renderBatch(data, size) {
for (let i = 0; i < data.length; i += size) {
yield data.slice(i, i + size);
}
}
const iterator = renderBatch(bigData, 150);
function scheduleRender(deadline) {
while (deadline.timeRemaining() > 5 && !iterator.next().done) {
// 执行一批渲染:drawPoints(currentBatch)
}
if (!iterator.next().done) {
requestIdleCallback(scheduleRender);
}
}
requestIdleCallback(scheduleRender);结合 Canvas 或 SVG 实现增量绘制
对 Canvas,可复用同一上下文,每批只 fillRect / strokeLine 少量图形;对 SVG,可动态 append 少量 <circle> 或 <path> 元素:
立即学习“Java免费学习笔记(深入)”;
- Generator 不直接操作 DOM/SVG,只产出“渲染描述对象”,如
{ type: 'point', x, y, r },解耦逻辑与视图 - 主渲染函数根据描述批量更新,支持撤销、回放、暂停(只需保存当前 iterator 状态)
- 配合
transform或clipPath优化可视区外元素跳过,进一步减少每批工作量
支持交互中断与状态恢复
当用户开始缩放、搜索或切换图层时,可立即暂停当前 Generator 迭代,保留 iterator 实例引用,后续恢复时从上次 yield 后继续:
- 用闭包或 class 成员保存 iterator,暴露
pause()/resume()方法 - 暂停时不做任何事,resume 时检查
done状态,继续调用next() - 若需重载数据,丢弃旧 iterator,新建一个即可,无副作用


















