Skip to content

从本地组件开发中沉淀的经验 ​

以下模式来自本地组件实现,涵盖交互、异步任务、持久化与资源释放,可按需用于自己的组件。

1. 联合设置透明画面与输入 ​

透明团团把角色多边形和输入面板矩形一起提交给 window.setInputRegions;根背景透明只负责画面。只圈住角色会使面板文字框点不到,把整个窗口设为命中又会遮住桌面。

做法是把“看见什么”和“哪里吃输入”分开,展开/收起后重算整组几何,可信编辑期间让宿主接管。来源:examples/transparent-pet/main.js 的 regions/configure 与运行协议。验收时分别点击角色内部、空白、输入框,并从宿主恢复纯穿透状态。

2. 状态变化要合并,不能排队追赶 ​

团团的 updating/dirty 和花园的 applying/desired 保证最多一个正在提交和一个最新目标。连续切换展开/折叠时,若每次都保存一份异步队列,旧的 setSize 可能在新配置后又把界面改回去。

先保留最新意图,等待当前调用完成再消费;失败项不自动无限重试。花园还用 configEpoch 防止较旧 config.set 响应覆盖新 config.changed。来源:examples/edge-garden/main.js。测试快速交替切换并在请求间插入配置变化,最终状态应对应最后一次有效意图。

3. 分别处理解锁和恢复 ​

锁屏与挂起可以同时成立。只保留 paused 一个布尔值时,收到 unlocked 就可能在系统仍挂起的情况下恢复绘制。

团团和计算画布使用独立停止原因集合:locked/unlocked 只改变锁屏原因,suspending/resumed 只改变挂起原因。还有 document.hidden、宿主 visible 和 sessionLocked 的独立检查。来源:examples/transparent-pet/main.js、examples/worker-canvas/main.js。测试 locked → suspending → unlocked 时仍应停止,直到 resumed。

4. 取消读取,和撤回修改,是两回事 ​

文件工具明确说明“保存未完成确认,请检查所选位置”,复制取消也不声称剪贴板能撤回。业务取消信号不能回滚服务已经提交的外部副作用。

提醒面板把“修改已经确认”与“后续列表刷新”分开:保存成功后取消列表,仍保留保存成功提示。修改响应未确认则提示手动刷新核对。来源:examples/file-tool/main.js、提醒协议。测试在写入前、响应丢失、成功后读列表三个位置取消,文案不能混淆。

5. 单槽直到真正收尾才释放 ​

取消按钮不应立即开放另一个同类操作。底层请求可能仍在有界退出,如果一按取消就创建新任务,快速点击仍能累积挂起工作。

提醒工具保持操作槽直到原调用结束;计算画布的兼容报告也只有一个 controller。来源:提醒协议、examples/worker-canvas/main.js 的 reportController。测试连续开始/取消时同时存活操作数仍有上限。对可立即替换的纯读取任务,也要用代次阻止旧结果并遵守宿主在途额度。

6. Worker 绘制需要确认,不只是节流 ​

星河微光为状态消息加 sequence,收到匹配 applied 后才发下一份 latest。计算画布同样有 presentationInFlight/pendingPresentation 和五秒响应期限。仅按固定 interval postMessage 不能保证慢 Worker 不积压。

将用户计算与绘制状态分开,计算保持单任务,绘制只保留最新状态。异常/超时终止并明确重试,不永久重启。来源:examples/stardust/main.js、examples/worker-canvas/main.js。验证慢消费时队列有界,恢复只绘制当前状态。

7. OffscreenCanvas 取消后的重试要重建资源 ​

画布转交 Worker 后不能假定旧画布仍能用原初始化路径再次转交。计算画布取消时终止 Worker 并替换一个干净 canvas,供用户明确重试;pagehide 只释放,不再替换 DOM。

来源:examples/worker-canvas/main.js 的 cancel/stopWorker/pagehide。测试显式取消后重新计算可恢复,而页面离开时没有迟到 DOM 替换。

8. 保存成功之前不要宣布收益到账 ​

花园的模型、模拟与持久化分开;安装共享保存必须使用修订比较。另一个显示器同样有写资格,配置里不能自封“主屏”来绕过冲突。

先验证数据和修订,按关键业务检查点保存;SAVE_CONFLICT 重读合并。网络式响应丢失后先读确认,不能把取消当未提交。来源:存档/协作协议、examples/edge-garden 的游戏逻辑。验证两个写入者、旧修订、长离线和时钟倒退。

9. 初始状态、取消和降级也要能独立使用 ​

没有缓存时仍应有 CSS 静态预览;Worker 或 GPU 不可用不应让整个组件消失。减少动画要静态一帧,省电要降频,隐藏/锁屏/挂起要停止绘制,不是所有状态都执行同一个“暂停业务”。

星河缓存只是可重建静态预览,不是恢复 GPU 成功的证据。来源:星河模块与缓存协议。测试空缓存、损坏缓存、Worker 初始化失败和减少动画,不能依赖此前成功运行。

10. 开发重载使用校验副本 ​

源码监视等待至少一秒稳定后复制校验;无效候选保留成功版本。未保存配置草稿会延后自动激活,手动流程保留保存/放弃/继续编辑;开发抽屉提供重载,不提供手动恢复上一版本入口。

来源:开发模块。先确认绑定的是构建输出,再排查“为什么改了没生效”;不要通过复制宿主输出或绕过草稿保护解决重载问题。验证写到一半的文件、无效 manifest、草稿存在和目录消失。

11. 清理必须覆盖失败和离页 ​

文件工具在 pagehide 移除处理器、abort 当前操作并清预览;计算画布还关闭音频和 Worker。只在成功分支 close fileId/exportId 会让失败路径泄漏;只给成功回调加 stopped 检查也会让迟到错误覆盖旧页面。

来源:examples/file-tool/main.js、examples/worker-canvas/main.js。给每个句柄、订阅、计时器、对象 URL 指定所有者,用 finally 处理释放,并让离页不可逆失效。分别测试成功、拒绝、取消、超时和关闭。

如何使用这些经验 ​

新任务先按场景方案选例子,再用上面的失败场景做最小验证。

当前宿主协议 · SDK 0.1.1 · MIT