AI友好的可视化图形引擎自我革命:Meta2d.js 2.0 历时一年全新重写,性能与多人协作全面升级

0 阅读10分钟

前言

Meta2d.js 是一个国产开源的 2D 可视化引擎,用来快速搭建 Web 组态、SCADA、监控大屏、流程图、中控可视化以及图形编辑与交互等应用 —— 接入实时数据,设置动画和条件,画面实时自动更新,还支持绘制、编辑、交互。Meta2d.js以「数据驱动显示」的理念服务了大量工业与物联网项目,1.0 的性能表现已经足够能打。而今历时一年自我革命,全新重构重写 —— 渲染管线、事件拾取、动画系统、数据通信,每一层都推倒重来,只为让性能更上一层楼、让多人协作从无到有。

image.png

image.png

一、Meta2d.js是什么

Meta2d.js 是一个开源的2D 可视化引擎,核心是「数据驱动显示 + 动态交互」:

  • 数据变化,驱动画面实时变化
  • 条件、交互、消息、事件的即时响应

典型使用场景

  • 工业组态 / SCADA:电力、水务、能源、工厂产线监控,设备点位、管线、告警联动;

  • 监控大屏 / 中控可视化:智慧楼宇、机房动环、交通调度,动图与实时数据同屏;

  • 流程图 / 架构图编辑器:拓扑图、ER 图、组织架构,自带编辑交互开箱即用;

  • 报表 / 数据可视化:实时数据驱动的大屏报表;

  • 可视化产品底座:MIT 协议,基于它二次开发自己的设计器 / 编辑器。

二、AI 时代的可视化底座

Meta2d.js 2.0 不内置 AI 模型,却天然对 AI 友好:

  • 数据驱动,输出即渲染

    引擎的核心是「数据 + 算法 + 风格 = 栩栩如生」,本质上就是一份结构化 JSON。AI生成可视化数据后,引擎即刻显示 —— 实现「AI 生成 → 可视化」即时呈现。

  • 支持生成式、渐进式体验

    可以很方便的支持 AI 生成式、渐进式的数据可视化展示。

  • 性能扎实,支持海量图元

    AI 一次性生成10万、100万+节点都能即时显示、流畅运行。

  • 人机同屏协作,改动可追溯

    多人协作不止于人 —— AI Agent 也可以作为协作者实时增删改画布。差量 patch 让每一次 AI 改动都可同步、可回放、可追溯;五通道实时数据管道 + 数据点绑定,让 AI 推理结果、设备数据直接驱动画面联动。

一句话:AI 负责 "生成",Meta2d 负责 "渲染、交互、协作" —— 这就是 AI 时代可视化底座该有的样子。

三、性能强劲,百万图元依旧实时联动

性能基准测试: 基于官方压力与性能基准测试(examples/benchmark)
测试环境: 8核 3.8GHz CPU,32GB 内存

图元性能:帧性能:内存(MB)备注
1万117 - 12044 - 50拖拽、缩放不影响
10万114 - 12080 - 110鼠标拾取不掉帧
100万109 - 117510 - 840鼠标拾取不掉帧

注:200 图片、2000 数据点、400 动画 都一样,没有再额外设置

10万图元,缩放网页以便容纳所有图元,画布不缩放
image.png

10万图元,不缩放网页,缩放画布
image.png

100万图元,不缩放网页,缩放画布

image.png

性能优化小过程:原计划2026年9月25号中秋节前发版2.0。我们测试大概10万图元是流畅的,真实生产案例中足以满足的。但是我们开发是基于“架构 -> 设计实现”的模式编写,性能优化原计划在发布后。恰逢 claude 5.5 和 gpt 6 发布,我们决定抱着尝试的态度让AI帮我们做深度性能优化,此前都是我们工程师凭着过去5年累积的经验去设计新的架构,有点担心AI“改乱”我们的代码。我们惊喜的是AI的评估和我们大致一致,并且优化改动的代码我们可接受。于是我们决定让AI帮我们做深度性能优化后发布,因为又需要大量的审核和测试,导致发布的延后,但优化后的性能确实超出我们预期。

AI分析:
meta2d 每个动画图元各自算脏区 → 各自 postMessage → 渲染 worker 各自 clip+clear+重绘;hover worker 还各自全屏清空重绘 N(动画图元数)× 2

meta2d 的单个原语实现(脏矩形、空间网格、Worker 分线程、样式 diff)都是对的,但帧内没有聚合层,所以复杂度是 O(动画图元数) 次独立重绘管线,而不是 O(1) 次。2 万图元时哪怕只有 200 个在动,也是每帧 400 次消息 + 400 次 clip/clear/draw + 400 次全屏 overlay 重绘。

四、与 Konva.js、Fabric.js、PixiJS 等绘图库的不同

都是优秀的 Canvas 技术栈,但定位完全不同:Konva / Fabric / Pixi 是 "画布基础能力" 提供者,Meta2d 是 "业务开箱即用" 的可视化引擎。

维度Meta2d.js 2.0Konva.jsFabric.jsPixiJS
定位业务级 2D 可视化引擎通用 Canvas 绘图交互库Canvas 对象模型库高性能 2D 渲染引擎
核心卖点数据驱动显示,开箱即用图形绘制与交互(拖拽 / 缩放 / 事件)对象模型与序列化(JSON/SVG 互转)渲染性能(WebGL 优先)
数据通信内置 MQTT/WS/HTTP/SSE/SQL + 数据点绑定无,需自接无,需自接无,需自接
条件告警 / 生命周期内置无无无
在线多人协作2.0 内置差量同步需自建需自建需自建
编辑器交互内置(吸附 / 层级 /undo/redo/Web 组件)部分,需自行组装部分(选择 / 变换)无
典型场景组态、SCADA、监控大屏、流程图画板、标注、H5 交互图片 / 海报编辑器游戏、高性能可视化
开源协议MITMITMITMIT

怎么选型:

  • 想要高性能渲染 → Meta2d.js / PixiJS;

  • 想要通用绘图交互 → Meta2d.js / Konva / Fabric;

  • 想要工业可视化业务开箱即用(组态、SCADA、大屏、流程图 + 实时数据 + 协作)→ Meta2d.js。

一句话:不用自己接 MQTT/WebSocket、不用自己写拾取和局部渲染优化、不用自己搭编辑器交互、不用自己实现多人协作 —— 选 Meta2d.js 2.0

五、Meta2d.js 2.0 关键设计

5.1 多线程架构

2.0 把整个引擎拆成 1 个主线程 + 4 个 Web Worker(packages/core/src/workers/):

  • 渲染线程 持有OffscreenCanvas,绘制指令不再经过主线程。拖拽、缩放、动画播放时主线程保持「零占用」;
  • 计算线程 负责拾取、视口裁剪、包围盒与脏区计算 —— 这些是编辑场景里每帧都会发生的重活;
  • 交互线程 负责图元动态交互下的状态管理和交互响应;
  • 工具线程 承载所有协议连接(MQTT/WebSocket/HTTP/SSE/SQL)和图片 / GIF 解析,握手、心跳、断线重连不影响界面;

5.2 局部重绘

1.x 采用整幅画布 clear + 全量重绘,逻辑简单稳定;2.0 在此基础上进一步升级为按包围盒的局部重绘。2.0 为每个图元维护包围盒(boundary) ,并预先计算其影响范围内的所有图元(penBoundarys),渲染线程只对脏区域执行 clearRect + clip:

// workers/render/worker.ts(关键逻辑)
if (boundary && boundary.width > 0 && pens === patchPens) {
  // 计算屏幕像素对齐的脏区
  ctx.clearRect(x, y, width, height);
  // 设置局部重绘区域
  ctx.beginPath();
  ctx.rect(x, y, width, height);
  ctx.clip();
}

几个典型的增量场景:

  1. 拖拽移动:先擦除并重绘「老位置」区域,再绘制「新位置」区域,两处脏区之外分毫不动:
// 1. 先擦除并重绘老位置区域
if (e.data.oldBoundary) {
  boundary = e.data.oldBoundary;
  renderPens(ctx, patchPens, true);
}
// 2. 重绘新位置区域
boundary = e.data.newBoundary;
renderPens(ctx, patchPens, true);

2. 悬停 / 选中:记录上一帧绘制过的图元集合(lastHoverPens / lastInActivePens),状态切换时只清除并重绘这些图元;

  1. 动画刷新:每一帧动画只重绘动画图元所在包围盒内的图元;
  1. 文字溢出感知:文字溢出 pen 范围时,textBox 会同步进拾取范围(textOutsides 回传 calc 线程),保证重绘完整覆盖。

5.3 空间网格拾取:从「全部遍历」到「只查一格」

拾取(pick)是编辑器的命门。1.x 采用线性遍历拾取,在万级图元下仍有明显优化空间;2.0 引入自适应空间网格索引(workers/calc/pick.ts),把拾取成本进一步大幅压低:

// 图元少于 2000 个时,整幅画布一个格
if (penMap.size < 2000) {
  cols = 1; rows = 1;
  cellSize = Math.max(width, height);
} else {
  // 动态计算网格行列数
  const size = Math.ceil(penMap.size / 1000);
  ...
}

拾取时先根据鼠标坐标定位到所在 cell,只遍历该格内的候选图元(grid[cell]),候选集合从「全部 N 个」降到「本格 ≤1000 个」。配合几个细节优化:

  • 连线外扩 5px:expandRect(pen, 5),避免细线难命中;
  • 曲线采样点缓存:linePoints Map 缓存贝塞尔曲线分段采样点,拾取曲线时不用每帧重算;
  • 旋转坐标反变换:pick 时把鼠标坐标变换到图元本地坐标系,旋转图元也能精确命中;
  • 文字溢出区域参与命中:textBoxs 纳入网格检测,点文字溢出部分也能选中。

5.4 原生解析 GIF / APNG,实现动图自由

工业大屏里 GIF 动图的播放一直受制于浏览器 的能力:无法控制帧率与暂停,频繁解码还会阻塞主线程。2.0 在工具线程里做了帧级原生解析:

  • 支持 GIF 与 APNG 两种动图格式,统一输出 { imageBitmap, duration } 帧序列;
  • 渲染线程内置 GIF 播放器(gifPlayers),按每帧 duration 推进帧索引,配合局部重绘只刷新动图所在区域:

  • 解析结果分批回传(每 50ms 或全部完成时批量 postMessage),ImageBitmap 直接转移所有权,不复制内存。

5.5 动画引擎优化

2.0 的动画播放器(workers/calc/animate.ts)整体搬进 calc 线程:关键帧插值在 Worker 内完成,每帧只把变化属性(changedProperties)发给渲染线程做局部重绘。1000+ 动画同屏播放时,主线程与渲染线程既不干扰,性能也大大幅度提升。

5.6 在线多人协作

这是社区期待已久的能力,也是 2.0 全新设计的patch特性考虑特性之一。设计要点:

  • 差量同步:与引擎补丁机制完全同的构协作消息结构,天然支持增量与协作渲染 —— 远端收到 patch 只做一次对应的局部重绘;
  • 历史回放:新成员进入房间,服务端回放历史差量,即完成协作统一;
  • 房间机制:通过 accessToken 作为房间号,同一房间共享同一份协作数据;
  • 可编程事件:协作数据通过 collaborate 事件对外广播,业务层可自行处理光标、通知、权限等扩展;

六、(几行代码)快速上手

npm install @meta2d/core @meta2d/<extension> --save
<le5le-meta2d />
import { createMeta2d, Mode } from '@meta2d/core';

createMeta2d();

const meta2d = document.querySelector('le5le-meta2d');

// 加载数据
fetch('data.json').then((res) => res.json()).then((data) => meta2d.open(data));
   
// 设置编辑模式。默认为运行模式
meta2d.setMode(Mode.Edit); 

结语

本着给用户带来更友好的体验,Meta2d.js 2.0 不惜全新重构,把「渲染、拾取、通信」重写架构设计,用空间索引 + 局部重绘把每一帧的无效计算压到最低,再用差量 patch 打通多人协作。对于组态、SCADA、大屏这类「图元多、数据实时、要交互编辑」的场景,带来更好体验和能力跃迁。

资源链接: