> **本文回答**：`MapCadLayer` 批量 `addEntity` 的正确姿势 —— 渲染合并、undo 事务、性能。

## 一、直接循环即可

```js
for (let i = 0; i < 10000; i++) {
  const line = new vjmapext.LineEnt([0, i], [100, i]);
  mapcadLayer.addEntity(line);
}
```

**不需要手动 bulk 接口**。`addEntity` 内部只标记 dirty，真正的重绘由 `requestAnimationFrame` 合并到下一帧——循环 1 万次也只会调度一次重绘。包内没有 `beginBulk`/`endBulk`/`bulkRun` 这类 API。

## 二、undo 事务：批量操作算一步撤销

```js
mapcadLayer.undoManager.beginTransaction();
try {
  for (const feat of features) {
    const ent = toEntity(feat);
    mapcadLayer.addEntity(ent);
  }
} finally {
  mapcadLayer.undoManager.endTransaction();
}
```

用户按一次 `Ctrl+Z` 会一次撤销整批。`beginTransaction`/`endTransaction` 支持嵌套，只有最外层 `endTransaction` 才入栈。

## 三、并行构造（Web Worker）

实体对象自身在主线程创建（访问 SDK），但**数据准备**可以放 worker：

```js
const raw = await workerPool.run('buildCoords', bigData);
raw.forEach(({ pts, color }) => {
  const poly = new vjmapext.PolylineEnt(pts);
  poly.color = color;
  mapcadLayer.addEntity(poly);
});
```

## 四、混合 GeoJSON + 实体

当"只看不交互"量大（几万 ~ 几十万），走 [primitive/geojson-source](../../../vjmap/references/primitive/geojson-source.md)；"要交互 / 编辑"的小量（< 1 万）走实体：

```js
// 展示层：50 万线
map.addGeoJSONSource('roads-bg', fcRoads);
map.addLineLayer('roads-bg', 'roads-bg', { lineColor: '#ccc', lineWidth: 1 });

// 业务层：10 条重点线，走实体便于编辑
importantRoads.forEach(r => mapcadLayer.addEntity(toLineEnt(r)));
```

## 五、样式批量

变更大量实体的颜色 → **单独有快路径**：`ent.styleChanged()`（而不是 `ent.changed()`），见 [bulk-style-update](bulk-style-update.md)。

## 六、删除批量

```js
idsToDelete.forEach(id => mapcadLayer.deleteEntity(id));
```

同样由帧调度自动合并重绘；要一步撤销就包在 `beginTransaction`/`endTransaction` 里。

## 七、常见坑

1. **创建实体时同步做网络请求** → 主线程卡；数据先拉齐，再循环 addEntity。
2. **undo 记录没包事务** → 用户要按 N 次 Ctrl+Z；批量操作用 `beginTransaction`/`endTransaction`。
3. **循环里 await 异步操作** → 把 addEntity 摊到多个帧、拉长总耗时；先同步构造完再一次性加。
