首页 / 资讯中心 / 文章详情

工业HMI性能优化:AG-UI协议与Canvas渲染引擎实践

工业HMI性能优化:AG-UI协议与Canvas渲染引擎实践 ★ FEATURED ARTICLE
1. 工业现场为什么需要一套自己的界面协议1.1 从一块触摸屏的卡顿说起我在一家做产线数据采集的团队里待了六年前四年半都在跟组态软件和触摸屏打交道。车间里最常见的一幕是操作工站在一台十几寸的工业平板前点一下按钮界面要愣个半秒才响应切个页面转圈两三秒赶上产线节拍快的时候操作工干脆绕过界面直接去按物理急停。这不是界面做得丑的问题是整套渲染链路在工业环境下水土不服。工业现场和消费级 App 的差别比很多人想象的大得多。消费端追求的是动画丝滑、视觉炫酷设备性能基本有保障工业端恰恰相反硬件往往是低功耗工控机、ARM 板子、老旧的安卓一体机GPU 性能羸弱内存紧张还要常年 7×24 小时运行。更麻烦的是工业界面里塞满了实时数据温度、压力、转速、报警状态这些数据每秒都在变如果每次数据更新都触发一次完整的界面重绘再强的硬件也扛不住。我们早期用的是传统 Web 方案DOM 结构一层套一层一个监控页面几百个节点数据一刷新浏览器的重排重绘直接把主线程堵死。后来换成 Canvas 渲染情况好转了不少但新的问题又来了Canvas 是一块画布画什么、怎么画、什么时候重画全靠自己管团队里每个人写出来的代码风格都不一样维护成本高得离谱。这时候我意识到光有渲染引擎不够还得有一套统一的界面描述协议把“界面长什么样”和“怎么把它画出来”这两件事彻底分开。这就是 AG-UI 协议和 Canvas 渲染引擎这套组合的由来。AG-UI 是一套面向工业场景的界面描述协议你可以把它理解成一份“界面说明书”用结构化的方式描述界面上有哪些元素、它们的位置关系、绑定哪些数据、响应哪些交互Canvas 渲染引擎则是这份说明书的“执行者”负责把描述翻译成实际的绘制指令高效地画到画布上。两者配合既解决了性能问题又解决了协作和维护问题。1.2 这套方案到底解决了谁的痛点先说清楚这套东西适合谁。如果你是做工业 HMI人机界面、SCADA 监控大屏、设备状态看板、产线数据可视化的开发者那这套方案基本就是为你准备的。尤其是那些硬件性能有限、数据刷新频繁、界面元素多、还要求长期稳定运行的场景传统方案要么跑不动要么维护起来让人崩溃。具体来说它解决三类人的痛点。第一类是前端开发者他们不想再为每个项目重复造轮子希望有一套统一的描述规范写一次界面逻辑换个渲染后端也能跑。第二类是工业现场的实施和运维人员他们需要界面能快速调整产线改个布局、加个仪表不用重新编译打包改配置就能生效。第三类是团队的技术负责人他们关心的是代码可维护性、多人协作效率以及长期演进的可能性。我见过太多团队在工业界面上反复踩坑有人用 DOM 硬扛性能上不去有人直接上游戏引擎学习成本高和业务系统对接困难还有人每个项目都从头写 Canvas 绘制代码最后没人敢改。AG-UI 协议加 Canvas 渲染引擎的思路本质上是把“描述”和“渲染”解耦让界面变成一份可配置、可复用、可跨端的数据而不是一堆散落在代码里的绘制指令。1.3 核心思路描述与渲染分离这套方案最核心的一句话就是界面是数据渲染是服务。AG-UI 协议定义了一套 DSL领域特定语言用 JSON 或类似的结构描述界面。一个按钮、一个仪表盘、一条趋势曲线在协议里都是一个有类型、有属性、有数据绑定、有事件声明的节点。这些节点组成一棵界面树树的结构就是界面的结构。Canvas 渲染引擎拿到这棵树之后做三件事解析、布局、绘制。解析是把协议节点转成引擎内部的渲染对象布局是计算每个对象在画布上的位置和尺寸绘制是调用 Canvas 的绘图 API把对象真正画出来。这三步里布局和绘制是最耗性能的也是优化的重点。为什么要把描述和渲染分开因为工业现场的界面需求变化太频繁了。今天加一个报警灯明天改一下仪表量程后天调整一下页面布局。如果描述和渲染耦合在一起每次改动都要动绘制代码风险高、效率低。分开之后界面调整只需要改协议描述渲染引擎本身不用动改完刷新一下配置就生效这对现场实施来说太重要了。而且描述和渲染分离之后同一份 AG-UI 描述可以对接不同的渲染后端。今天用 Canvas 2D明天性能不够了换 WebGL后天要上大屏换 SVG界面描述不用重写。这种灵活性在工业项目里价值极高因为工业项目的生命周期往往长达五到十年中间硬件和软件栈都可能换好几轮。2. AG-UI 协议的设计细节与 DSL 拆解2.1 协议节点的基本结构AG-UI 协议里每个界面元素都是一个节点。节点的基本结构包含几个关键字段类型、标识、属性、样式、数据绑定、事件、子节点。类型决定这个节点是什么比如按钮、文本、仪表、曲线、容器标识是节点的唯一名字用于查找和更新属性是节点特有的配置比如按钮的文字、仪表的量程样式控制外观比如颜色、边框、字体数据绑定声明这个节点跟哪个数据源关联事件声明节点响应哪些交互子节点用于构建嵌套结构。我举个实际的例子。一个显示温度的仪表节点在协议里大概长这样类型是 gauge标识是 temp_gauge属性里声明量程是 0 到 150 度样式里声明指针颜色和刻度颜色数据绑定指向一个叫 temperature 的实时数据点事件里声明点击时弹出历史趋势。整个节点就是一段结构化的数据没有任何绘制逻辑。渲染引擎读到这个节点就知道该画一个仪表量程多少指针指向哪点击该干什么。这种结构的好处是界面完全可序列化。你可以把整个界面存成 JSON 文件通过网络传输存进数据库或者由后端动态生成。现场要改界面改这个 JSON 就行不用重新发版。我们有个项目客户要求每天根据生产计划调整看板布局就是靠后端生成 AG-UI 描述前端渲染引擎直接消费实施人员完全不用碰代码。2.2 DSL 的语法设计与取舍AG-UI 的 DSL 设计有几个关键取舍这些取舍直接影响了它的可用性和性能。第一个取舍是扁平还是嵌套。嵌套结构更符合直觉容器里放子节点层级清晰但嵌套太深会导致遍历和布局计算变慢。我们的做法是限制嵌套层级一般不超过四层超过的部分用分组和引用机制来扁平化。第二个取舍是属性内联还是引用。有些属性是节点独有的直接内联在节点里有些属性是多个节点共享的比如主题色、字体、间距这些抽出来做成样式表节点通过引用使用。这样既减少了描述体积又方便统一换肤。工业现场经常要求白天模式和夜间模式切换样式表一换整个界面风格就变了不用逐个节点改。第三个取舍是静态描述还是动态表达式。工业界面里很多属性不是固定的比如报警灯的颜色取决于报警等级文本内容取决于实时数据。如果全部静态写死就没法响应数据变化如果全部用表达式解析开销又太大。我们的方案是区分静态属性和动态绑定静态属性在解析时确定动态绑定在数据更新时求值两者分开处理性能可控。这里要特别说一下 DSL 的错误处理。工业现场最怕的就是界面因为一个配置错误整个白屏。所以 AG-UI 协议要求渲染引擎对错误有容错能力遇到无法解析的节点跳过并记录日志而不是让整个界面崩溃。我们甚至做了一个降级机制如果某个复杂节点渲染失败自动降级成一个简单的文本提示保证操作工至少能看到关键信息。2.3 数据绑定与响应式更新机制工业界面的核心是数据。AG-UI 协议的数据绑定机制决定了界面能不能高效地响应数据变化。我们的做法是每个动态节点声明它依赖哪些数据点渲染引擎维护一张数据点到节点的反向索引表。当某个数据点更新时引擎通过索引表找到依赖它的节点只更新这些节点而不是重绘整个界面。这个机制听起来简单实现起来有几个坑。第一个坑是数据更新频率。工业现场的数据点可能每秒更新几十次如果每次更新都触发重绘性能还是扛不住。我们的做法是引入帧率控制和批量更新数据更新先写进一个待处理队列渲染引擎按固定帧率比如 30 帧或 60 帧批量处理队列里的更新合并同一帧内的多次更新只重绘一次。第二个坑是依赖关系的维护。节点和数据点的依赖关系不是一成不变的界面切换、节点增删都会改变依赖。如果依赖表更新不及时就会出现数据变了界面不刷新或者界面刷新了但数据是旧的。我们的做法是在节点挂载和卸载时同步更新依赖表并且定期做一致性校验发现不一致就重建索引。第三个坑是局部重绘的边界。Canvas 的局部重绘需要精确计算脏矩形算大了浪费性能算小了会留下残影。我们的做法是给每个节点维护自己的包围盒数据更新时把受影响节点的包围盒合并成脏矩形只重绘这个区域。对于有重叠的节点脏矩形要向外扩展几个像素避免边缘残影。这个扩展量是实测出来的一般 2 到 4 个像素比较稳妥。3. Canvas 渲染引擎的核心实现3.1 渲染管线的三个阶段Canvas 渲染引擎的渲染管线分三个阶段解析、布局、绘制。解析阶段把 AG-UI 描述转成引擎内部的渲染对象树这个过程包括类型映射、属性校验、样式合并、数据绑定建立。布局阶段计算每个渲染对象的位置和尺寸这个过程要考虑容器的布局模式、节点的尺寸约束、以及节点之间的相对关系。绘制阶段调用 Canvas API 把对象画出来这个过程要考虑绘制顺序、裁剪区域、以及脏矩形优化。解析阶段最容易被低估。很多人觉得解析就是 JSON 转对象没什么技术含量。实际上解析阶段要做的事情很多类型映射要把协议里的类型字符串映射到具体的渲染类属性校验要检查必填属性有没有缺、属性值合不合法样式合并要把节点自己的样式和引用的样式表合并处理优先级数据绑定要建立节点和数据点的关联。这些工作如果放到绘制阶段做每次重绘都要重复一遍性能浪费严重。所以我们的原则是能在解析阶段做完的绝不拖到绘制阶段。布局阶段是性能大头。工业界面里经常有几十上百个节点每个节点的布局计算如果都是独立的累加起来就很可观。我们的优化策略是缓存布局结果只有影响布局的属性变化时才重新计算。比如一个仪表的位置变了只需要重新计算它和它兄弟节点的布局父容器和其他无关节点不用动。这种增量布局的思路让界面在频繁更新时依然保持流畅。绘制阶段的关键是减少状态切换。Canvas 的绘图 API 每次切换填充色、描边色、字体都有开销。我们的做法是在绘制前对节点按样式分组相同样式的节点连续绘制减少状态切换次数。另外对于静态内容我们预渲染到离屏 Canvas绘制时直接贴图避免重复的路径计算和文字排版。3.2 脏矩形与局部重绘的工程实践脏矩形是 Canvas 性能优化的核心手段但用好它并不容易。我踩过的坑包括脏矩形算小了导致残影算大了性能没提升多个脏矩形重叠导致重复绘制以及脏矩形和变换矩阵配合出错。先说脏矩形的计算。每个节点在绘制时引擎会记录它的包围盒。数据更新时受影响的节点包围盒合并成脏矩形。但这里有个细节如果节点有旋转、缩放等变换包围盒要按变换后的实际范围计算不能直接用原始尺寸。我们早期就吃过这个亏一个旋转的指针脏矩形按原始尺寸算结果指针转过去的地方留下了残影。再说脏矩形的合并。如果一帧内有多个不连续的脏矩形是逐个重绘还是合并成一个大矩形逐个重绘的绘制面积小但每次重绘都要清空和重建裁剪区域开销也不小合并成一个大矩形绘制面积大但只需要一次裁剪设置。我们的实测结论是脏矩形数量少且分散时逐个重绘更划算脏矩形数量多或者彼此靠近时合并更划算。引擎里做了一个简单的启发式判断根据脏矩形数量和总面积动态选择策略。还有一个容易被忽略的点是背景处理。局部重绘时脏矩形区域要先清空再重绘。如果界面有背景色或背景图清空后要先把背景画回来再画节点。如果背景是纯色直接填充就行如果背景是渐变或图片就要从预渲染的背景层里裁剪对应区域贴回来。我们专门维护了一个背景层界面背景变化时才更新平时局部重绘直接从背景层取像素省去了重复绘制背景的开销。3.3 高频数据下的帧率控制策略工业现场的数据刷新频率差异很大。温度、压力这类模拟量可能几百毫秒更新一次开关量、报警状态可能几毫秒就变一次而像电机转速这种每秒几十次更新很常见。如果数据来一次就重绘一次界面必然卡顿。所以帧率控制是必须的。我们的帧率控制策略分三层。第一层是数据层数据更新先写入待处理队列不直接触发重绘。第二层是调度层渲染引擎按固定帧率从队列取数据合并同一帧内的多次更新。第三层是绘制层如果这一帧的脏矩形和上一帧完全一样说明界面没有实际变化直接跳过绘制。帧率定多少合适消费级应用一般追求 60 帧工业界面其实 30 帧就足够流畅了操作工对界面的响应要求没那么高稳定比丝滑更重要。我们把默认帧率定在 30 帧同时提供配置项高性能设备可以调到 60 帧低性能设备可以降到 15 帧甚至 10 帧。实测下来30 帧在绝大多数工业平板上都能稳定运行CPU 占用率比 60 帧低一半左右。还有一个细节是数据合并的策略。同一帧内同一个数据点可能更新多次只保留最后一次的值就行。不同数据点更新如果它们影响的节点有重叠合并处理如果没有重叠各自更新各自的脏矩形。这种合并策略让高频数据下的绘制次数大幅减少我们有个项目数据点每秒更新上百次合并后实际绘制只有每秒 30 次性能提升非常明显。4. 工业现场落地中的典型问题与排查4.1 界面白屏与渲染失败的排查路径工业现场最怕白屏。操作工看不到界面产线就得停。我们遇到过好几次白屏排查下来原因各不相同整理成一套排查路径基本能覆盖九成以上的情况。第一步看控制台有没有报错。AG-UI 解析失败、数据绑定找不到数据源、Canvas 上下文获取失败这些都会在控制台留下痕迹。但工业现场的浏览器往往没有开发者工具所以我们在引擎里内置了错误上报出错时把错误信息写到一个隐藏的日志区域现场人员可以通过特定手势调出日志。第二步检查 AG-UI 描述是否合法。最常见的问题是 JSON 格式错误比如多了个逗号、少了引号。这种问题在配置动态生成时特别容易出现。我们的做法是在协议里加版本号和校验和渲染引擎加载描述前先校验不合法就拒绝加载并保留上一个可用版本避免白屏。第三步检查数据源连接。界面渲染出来了但全是空值或者一直显示“无数据”通常是数据源没连上。工业现场的网络环境复杂数据源可能是 OPC、Modbus、MQTT任何一种连接出问题都会导致界面无数据。我们的做法是给每个数据绑定加超时和降级显示数据源断了显示上一次的值并标记为过期而不是显示空白。第四步检查 Canvas 上下文。有些工业浏览器对 Canvas 支持不完整或者 GPU 加速被禁用导致 Canvas 初始化失败。这种情况的典型表现是界面框架在但画布区域一片空白。解决办法是检测 Canvas 可用性不可用时降级到 DOM 渲染虽然性能差些但至少能用。4.2 触摸交互与事件处理的坑工业现场的交互方式和消费端差别很大。操作工可能戴着手套操作触摸精度低可能用触控笔点击区域小还可能快速连续点击产生大量事件。这些都对事件处理提出了特殊要求。第一个坑是点击区域太小。消费端按钮 44 像素就算合格了工业现场戴手套操作点击区域至少要 60 像素以上重要按钮甚至要 80 像素。我们在 AG-UI 协议里给交互节点加了最小点击区域的约束渲染引擎在布局时自动扩展点击热区视觉上按钮还是原来的大小但实际可点击范围更大。第二个坑是事件穿透和冒泡。Canvas 是一整块画布没有 DOM 的事件冒泡机制所有事件都要自己分发。如果处理不好点击一个按钮可能同时触发它下面图层的点击事件。我们的做法是维护一个反向的节点命中测试表从最上层节点开始测试命中就停止不继续往下传。对于需要冒泡的场景在协议里显式声明事件传播策略。第三个坑是高频点击的去抖。操作工着急的时候会连续猛点如果每个点击都触发业务逻辑可能造成重复提交。我们在事件层加了去抖和节流同一个按钮在 300 毫秒内只响应一次同时给用户视觉反馈让操作工知道点击已经生效不用重复点。4.3 内存泄漏与长时间运行的稳定性工业界面要求 7×24 小时运行内存泄漏是隐形杀手。我们有个项目界面跑了两天之后越来越卡最后直接崩溃排查发现是数据绑定的监听器没有正确移除每次界面切换都残留一批监听器越积越多。Canvas 渲染引擎的内存泄漏主要来自几个地方事件监听器、数据绑定、离屏 Canvas、定时器。事件监听器要在节点卸载时移除数据绑定要在节点销毁时解除离屏 Canvas 要复用而不是每次新建定时器要统一管理组件销毁时清理。我们后来做了一套资源生命周期管理每个渲染对象都有明确的创建和销毁时机销毁时自动清理关联资源泄漏问题才彻底解决。还有一个容易被忽略的是 Canvas 本身的尺寸。有些项目为了适配不同分辨率动态调整 Canvas 尺寸但调整时没有释放旧的位图缓冲导致内存持续增长。正确的做法是调整尺寸前先把 Canvas 宽高设为 0触发浏览器回收再设置新尺寸。这个技巧在移动端浏览器上尤其重要。5. 性能优化的实测数据与调优经验5.1 不同渲染策略的性能对比我们在同一台工业平板上做了几组对比测试硬件是四核 ARM 处理器2GB 内存安卓系统。测试场景是一个包含 120 个节点的监控页面数据每秒更新 50 次。测试结果如下表渲染策略平均帧率CPU 占用内存占用界面响应延迟全量重绘12 帧78%180MB400ms脏矩形局部重绘28 帧35%150MB80ms脏矩形加离屏缓存30 帧28%165MB60ms脏矩形加离屏缓存加帧率控制30 帧22%160MB70ms从数据可以看出脏矩形局部重绘是性能提升最大的一步帧率从 12 帧提升到 28 帧CPU 占用降了一半多。离屏缓存进一步降低了 CPU 占用但内存略有增加因为要维护缓存位图。帧率控制主要降低 CPU 占用对帧率本身没有提升因为帧率已经到顶了。这里要说明的是这些数据是在特定硬件和场景下测的换硬件、换场景数值会变但趋势是一致的局部重绘是核心优化离屏缓存和帧率控制是锦上添花。如果资源有限优先做局部重绘。5.2 参数调优的实操建议渲染引擎有几个关键参数调好了性能提升明显调不好反而拖后腿。第一个是脏矩形扩展量前面说过一般 2 到 4 像素。太小会残影太大会浪费性能。我们的做法是默认 3 像素同时提供配置项遇到特殊场景可以调整。第二个是离屏缓存的失效策略。离屏缓存不是越多越好缓存太多内存吃不消缓存失效太频繁又失去意义。我们的策略是静态节点长期缓存动态节点按更新频率分级高频更新的节点不缓存中低频的缓存并在数据变化时失效。这个分级阈值可以配置默认是每秒更新超过 10 次的节点不缓存。第三个是帧率。前面说了默认 30 帧高性能设备可以调到 60 帧低性能设备降到 15 帧。但要注意帧率不是越高越好工业界面的数据更新频率往往跟不上高帧率盲目提高帧率只会浪费 CPU。我们的建议是先测数据更新频率帧率设为数据更新频率的两倍左右就够了。第四个是批量更新的队列长度。队列太长数据延迟大队列太短合并效果差。我们的默认值是 3 帧的缓冲也就是数据更新后最多等 3 帧就会被处理。这个值在大多数场景下表现均衡极端高频场景可以调小极端低频场景可以调大。5.3 低端硬件上的降级方案工业现场不可能全是高配硬件低端设备上的降级方案是必须的。我们的降级策略分几级第一级是降低帧率从 30 帧降到 15 帧第二级是关闭离屏缓存减少内存占用第三级是简化绘制比如把渐变改成纯色把阴影去掉把复杂路径简化成矩形第四级是降级到 DOM 渲染虽然性能差但兼容性最好。降级的触发条件可以是自动的也可以是手动的。自动降级根据帧率和内存占用判断连续几秒帧率低于阈值就降一级。手动降级通过配置项控制现场实施人员可以根据实际情况调整。我们建议默认开启自动降级同时保留手动覆盖的能力因为自动判断不一定准确现场人员更了解实际情况。降级方案的实施要注意平滑过渡。降级过程中界面不能闪烁或跳变否则操作工会以为出故障了。我们的做法是降级时保持界面布局不变只改变绘制方式视觉上尽量平滑。比如从渐变降级到纯色选一个和渐变主色接近的纯色操作工基本察觉不到。6. 从协议到现场一套可复用的落地方法6.1 项目初期的协议设计要点如果你准备在自己的项目里用这套方案协议设计是第一步也是最关键的一步。我的建议是先梳理界面元素清单把项目里所有可能出现的界面元素列出来分类整理。工业界面常见的元素包括文本、数值、按钮、开关、指示灯、仪表、进度条、趋势曲线、表格、容器、分组。列完清单再为每类元素设计协议结构。设计协议结构时要预留扩展字段。工业项目的需求变化快今天没有的功能明天可能就要加。协议里留一个扩展字段新需求先往扩展字段里塞稳定后再正式纳入协议。这样既保证了协议的稳定性又不影响新功能的快速上线。还要考虑协议的版本管理。协议一旦发布就有多个项目在用不能随便改。我们的做法是协议带版本号渲染引擎兼容多个版本新版本协议增加功能时保持向后兼容。如果实在要做不兼容的改动就升大版本号同时提供迁移工具帮老项目平滑升级。6.2 渲染引擎的模块划分与协作渲染引擎的代码结构直接影响可维护性。我们的引擎分几个核心模块解析器、布局器、绘制器、事件管理器、数据绑定管理器、资源管理器。每个模块职责单一模块之间通过明确的接口通信方便单独测试和替换。解析器负责 AG-UI 描述到渲染对象的转换它不关心布局和绘制只负责把描述翻译成对象。布局器负责计算位置和尺寸它不关心对象是什么类型只关心对象的布局约束。绘制器负责调用 Canvas API它不关心对象从哪来只关心怎么画。事件管理器负责命中测试和事件分发。数据绑定管理器负责维护数据点和节点的关联。资源管理器负责离屏缓存、图片、字体等资源。这种模块划分的好处是每个模块可以独立优化。比如布局器性能不够可以单独重写不影响其他模块。绘制器要支持新的绘制方式也只改绘制器。团队协作时不同人负责不同模块接口定好并行开发不冲突。6.3 现场部署与远程更新的实践工业现场的部署和消费端差别很大。现场往往没有稳定的网络不能依赖在线更新设备可能没有应用商店不能自动升级操作工不懂技术不能手动操作。所以现场部署要考虑离线更新和远程维护。我们的做法是界面描述和渲染引擎分离部署。渲染引擎随应用打包版本相对稳定界面描述存在本地文件或本地数据库支持远程下发更新。远程更新时新描述先下载到本地临时目录校验通过后原子替换旧描述渲染引擎重新加载。如果新描述有问题自动回滚到旧版本。远程更新还要考虑灰度发布。产线上有多台设备不能一次全更新万一有问题整条线都停了。我们的做法是分批更新先更新一台观察一段时间没问题再更新下一批。更新过程中设备可以正常使用更新完成后提示操作工刷新界面生效。现场部署还有一个细节是配置管理。不同产线、不同设备的界面配置可能不同这些配置要能方便地管理。我们的做法是把配置抽出来做成独立的配置文件按设备编号或产线编号组织部署时根据设备信息加载对应配置。这样同一套引擎和描述换个配置文件就能适配不同现场实施效率高很多。7. 这套方案后续还能怎么演进7.1 从 Canvas 2D 到 WebGL 的平滑过渡Canvas 2D 在节点数量不多时够用但节点数量上去之后比如上千个节点的大屏2D 的绘制性能就到瓶颈了。WebGL 利用 GPU 并行绘制性能上限高得多。我们的协议设计时已经考虑了这一点AG-UI 描述不依赖具体的渲染后端换 WebGL 只需要重写绘制器协议和布局器不用动。从 2D 过渡到 WebGL 的难点在于2D 的很多绘制方式在 WebGL 里没有直接对应。比如文字渲染2D 有 fillTextWebGL 要自己生成文字纹理比如路径填充2D 有 fillWebGL 要自己三角化。这些都需要额外的工程投入。我们的建议是节点数量在几百以内2D 足够上千节点再考虑 WebGL而且要评估投入产出比。7.2 协议生态与工具链的完善一套协议要真正好用光有协议本身不够还要有配套的工具链。我们目前在做几件事一是可视化编辑器让实施人员通过拖拽配置界面不用手写 JSON二是协议校验工具在配置提交前检查合法性避免现场出错三是性能分析工具帮开发者定位渲染瓶颈。可视化编辑器对现场实施价值最大。工业现场的实施人员往往不是专业开发者让他们手写协议不现实。有了可视化编辑器拖拖拽拽就能配出界面效率高很多。编辑器生成的协议和手写的完全兼容开发者可以用编辑器快速搭原型再手动微调细节。协议校验工具解决的是配置错误问题。前面说过配置错误是白屏的主要原因之一。校验工具在配置生成后、下发前做一次全面检查把错误拦在上线之前。校验规则可以配置不同项目可以有不同的严格程度。7.3 面向未来的可扩展性设计工业项目的生命周期长技术栈会变需求会变协议和引擎都要为未来留余地。我们的做法是协议层面核心结构保持稳定扩展能力通过扩展字段和插件机制提供引擎层面核心管线保持稳定渲染后端、数据源、事件处理都做成可插拔的模块。插件机制是关键。工业现场的需求千奇百怪不可能全部预置在引擎里。我们提供插件接口现场遇到特殊需求可以写插件扩展不用改引擎核心。插件可以扩展协议节点类型、扩展渲染方式、扩展数据源、扩展事件处理。这样既保证了引擎的稳定性又保证了灵活性。最后说一点个人体会。这套方案我们打磨了三年多中间推翻重来过两次踩过的坑不计其数。最大的教训是不要一开始就追求大而全先把核心场景跑通再逐步扩展。工业现场的需求是长出来的不是设计出来的。先解决最痛的那个点让现场用起来再根据反馈迭代比闭门造车强得多。
阅读完成 · 觉得有帮助?
咨询建站