最成熟方案是用WebAssembly替换JavaScript几何核心计算模块;需分层处理,将3D布尔运算、网格修复等强顺序依赖、浮点密集、拓扑判定任务下放WASM,UI交互仍由TS+WebGL管理。

直接用 WebAssembly 替换 JavaScript 中的几何核心计算模块,是目前最成熟、见效最快的方案。关键不在“能不能跑”,而在于“怎么分层”和“哪些算子必须下放”。
明确哪些计算必须交给 WASM
浏览器里做 3D 布尔运算(并、差、交)或网格修复,JavaScript 很难扛住——尤其是输入模型面数超 5 万、拓扑不闭合、存在自相交时。这类任务有三个典型特征:强顺序依赖、大量浮点密集运算、需精确拓扑判定。这些正是 WASM 的优势区。
- 布尔运算本身(如 OpenCascade 的
BRepAlgoAPI_Fuse或 Manifold 的union)必须在 WASM 层实现,不能靠 JS 模拟 - 网格简化、法向量重计算、包围盒批量更新等中间步骤也建议下放,避免主线程阻塞
- 纯 UI 交互(如拖拽、高亮、视角旋转)仍由 TypeScript + WebGL 管理,不参与 WASM 调用链
选对底层引擎并精简编译
不是所有 CAD 内核都适合浏览器。OpenCascade、Manifold、CGAL 是主流选择,但浏览器里必须做裁剪。以 Chili3D 为例,它只编译了 TKBool(布尔)、TKMesh(网格)、TKGeomAlgo(几何算法)等 7 个关键工具包,而非全部 50+ 个,最终 WASM 模块控制在 8–12 MB。
- 禁用运行时异常捕获(
-s DISABLE_EXCEPTION_CATCHING=1),提升布尔运算稳定性 - 堆内存初始设为 64 MB,允许增长但上限设为 2 GB,防止移动设备 OOM
- 启用 LTO(Link-Time Optimization)和
-Os优化,减少二进制体积与指令分支
设计安全高效的 JS/WASM 数据通道
几何数据通常以顶点数组(Float32Array)、索引数组(Uint32Array)或 BREP 序列化字符串形式在 JS 和 WASM 间传递。直接传 ArrayBuffer 最快,但需手动管理内存生命周期。
- 用
WebAssembly.Memory分配共享线性内存,JS 写入顶点坐标,WASM 读取并返回结果偏移量 - 避免频繁分配/释放内存:采用内存池(memory pool)复用已分配块,尤其适用于连续编辑场景
- 布尔运算结果若含新拓扑结构(如新增边、环),建议由 WASM 序列化为紧凑 JSON 或自定义二进制格式,再由 JS 解析为 Three.js 或 Babylon.js 兼容对象
处理实际工程中的鲁棒性问题
真实用户上传的 STL/OBJ 模型常有破面、缝隙、非流形边等问题,原生布尔运算容易崩溃或卡死。不能把问题全丢给 WASM,得加一层“前端守门员”。
- JS 层先做轻量预检:检查顶点数量是否超阈值(如 >50 万)、是否有 NaN 坐标、面片是否全部朝外
- WASM 层开启拓扑日志(如 Manifold 的
validate标志),失败时返回错误码而非静默挂起 - 对耗时超 800ms 的运算自动降级:改用近似布尔(voxel-based union)或提示用户简化输入

















