refactor(danmuku): [PKG-DANMUKU-05] own renderer settings and heatmap resources

This commit is contained in:
Harvey Zhao committed 2026-09-13 20:45:16 +08:00
1 parent 12332df221
commit 053d211fb0
38 files changed
+65630 -2420

No files matched your search

File diff suppressed because it is too large. Load diff
@@ -0,0 +1,118 @@
# PKG-DANMUKU-05 渲染、设置和热力图资源归属
本步完成JS职责整理,完整自有TS、Worker消息和已安装声明消费者归06。渲染模块负责
节点和几何,设置模块拆为协调器、模板/icons、Slider、发送、生命周期及全局样式;
热力图拆为采样、曲线计算和control生命周期。实际维护地图见包内
[ARCHITECTURE.md](../../packages/artplayer-plugin-danmuku/ARCHITECTURE.md)。
## 实现与兼容
- renderer接管原节点分配、样式、位置快照及暂停/恢复几何,scheduler继续决定操作
是否有效;两者之间保留generation与节点身份检查。destroy(false)仍移除自己的
弹幕节点、清除引用与空闲池,保留其他节点。替换加载仍执行旧整层清空,并在
释放归属记录前移除已被移动到层外的自有节点,保留层外无关内容。
- Setting在创建资源前登记销毁;自身初始化失败清理资源,入口再回滚已创建的
Danmuku/Worker并保留原错。精确解绑art监听、proxy和registry条目;某项解绑
抛错仍清理其他项。旧核心5.4.0的proxy返回函数需配合events.remove删除登记。
- pending beforeEmit与销毁竞速,销毁后不清input、不加锁、不迟到发送。保留
option receiver及严格true;普通发送仍同步插入、清input和启动原倒计时。
新增对emit返回Promise的局部观察,继续使用原console.error出口,不改为插件error。
- mount/fullscreen移动同一节点;销毁只移除自有设置DOM。宿主dataset/display按
最后写入值及实例归属恢复;共享mount保留存活实例,用户后续写入不被覆盖。
原始display的!important通过真实浏览器验证。全局样式仍在import时安装且不随
单实例销毁,DOMContentLoaded等待在重复bundle间去重,触发后解除监听。
- 热力图窄宽度和无效sampling使用正步长,非法尺寸/duration不生成NaN SVG。采样
由逐bin扫描整队列改为排序及二分计数,保留原浮点步进、严格左开右闭和数值边界。
曲线与旧源码、实际5.3.0 main/legacy逐字对照;points事件仍只复制外层,内层y
原地变化及重复调用累积保持,未静默改成immutable。
- 不设置任意100000数量上限,合法100001+采样/自定义点继续工作。仅拒绝不可表示
的数组长度、非有限参数或无法推进的数值步长;不声称任意巨大输入CPU成本有界。
- 无冲突的首个gradient保留旧heatmap-solids,其他实例使用独立ID;同文档重复
bundle也检查实际ID占用。heatmap-start/stop局部钩子、control名、样式与进度保持。
control卸载解除订阅,销毁不误删后来替换的同名control。
- 工厂门面、返回身份、getter、静态icons、合法输入和原轨道Worker算法保持。
不修改公共声明、分发入口或消费者运行时依赖。版本递增仍由统一版本任务实施。
## 验证及证据边界
源码、正式main、正式legacy各159项联合测试通过:原输入/解析/调度/Worker104项,
Setting36项、heatmap14项、renderer5项。每组101项随候选实现变化,另58项固定为
原Worker模块18、历史数值3、历史Setting18、直接heatmap14、直接renderer5;不能
把这些共同测试重复描述成不同产物覆盖。完整yarn test:danmuku为245项通过。
最终源码、main、legacy各138项原生浏览器通过:输入24、调度66、资源48,共414项。
每种实现使用2并发,最终报告unexpected/skipped/flaky均为0,retries为0。此前的
手工诊断和失败分别留档,不把最终通过描述成此前从未失败或负载问题已关闭。
实际已发布5.4.0和候选5.4.1核心,Chromium、Firefox、Windows WebKit。
覆盖真实视频/Worker、旧调度轨道、pending发送和计时器、外部及共享mount、初始化
回滚、原生!important、destroy(false)和重复bundle热力图。WebKit不是Safari真机。
完整构建生成main/legacy/esm并与docs/compiled逐一核对字节;ESM只计构建与复制,
不列入额外运行矩阵。源码/测试lint、Yarn冻结安装、严格工具链、全仓366生产TS与
消费者检查通过;未迁移JS不计入TS覆盖。早前被中断的typecheck日志不作为成功证据。
内置浏览器Chrome/152.0.0.0打开现有8082 docs编辑器及danmuku示例,使用正常yarn dev
构建和本地video.mp4/danmuku.xml:播放时间推进至46.89784、实际解码宽640,暂停后
保持46.911033;真实弹幕可见,示例异步beforeEmit发送完成后input清空,按钮恢复。
这是开发示例smoke,不是实际发布包或设备验收。读媒体时两次调试调用失败已记录,
不混同为页面错误,也不从一次截图推断无后台工作。
移动节点修正后,重新正常构建dev示例并在单元测试结束后重载验证:发送
Final resource verification,beforeEmit记录媒体时间0.267138,真实播放UI推进到
00:47,随后暂停在53.404841,后次原生读取仍为同值,解码宽640,input为空且发送
按钮恢复。页面warning/error列表为空。一次旧AX索引因开发重载失效,一次只读
video locator读取超时;使用当前UI和支持的CDP只读接口完成最终取证,均单独记录。
本步新增根devDependency linkedom@0.18.13并维护唯一yarn.lock,用于真实模板解析、
selector和事件测试,不随播放器发布。其[官方说明](https://github.com/WebReflection/linkedom)
明确不是完整浏览器;测试受控几何/计时器与真实浏览器证据分别记录。根test:unit和
test:danmuku加入三组新测试,浏览器spec沿既有CI发现。远端CI未在本步执行。
## 失败如何处置
- 旧04正式main的两核心Chrome六项资源回归均失败:外部DOM残留、pending完成后
清input并加锁、锁计时器保留及renderer节点引用残留。修复后由最终矩阵验证。
- renderer首轮受控检查因冻结假Element没有removeChild报错,仅给候选helper补
删除语义;冻结历史helper不改。随后原109项联合检查通过,另用Linkedom和原生
DOM断言真实节点删除,避免假DOM掩盖清理。
- 最后复审复现另一条资源遗漏:节点移到body后,替换加载清空归属集合但未移除
层外节点,后续destroy也无法清理。增加红例后,clear先释放自有节点再执行原
整层清空;受控回归验证层外无关节点保留,并新增两核心三引擎真实DOM用例。
- 中间热力图100000硬上限在复审中被否决。大输入两个红例中,一个巨大差异格式化
导致断言报告内存分配失败,另一个实际返回null。移除上限,并在比较大数组前先
断言长度,最终完整采样、曲线及内层mutation通过,不保留不兼容限制。
- 三引擎首轮128/132通过。两个WebKit例把打字/点击期间所有一秒定时器都当作
发送锁,捕获了额外计时器;改为从beforeEmit的同步发送续体观察初始锁ID,仍
要求该真实ID在销毁时清除。另两个取消/恢复例在预期时间未进入beforeVisible,
Worker请求为0。其目的在验证进入准备后的生命周期,改为明确建立ready前置
状态;原真实时间、轨道及数值例保持。不能据此宣称所有负载下的时间窗口无遗漏,
此项由LOAD-01留给07采集真实帧/媒体时间和压力证据。第一次ready夹具修改又引入
六个seek失败:旧项变为永久ready,seek后重新进入未结束的gate;恢复它按媒体时间
触发,仅恢复/新续行项设ready。NaN与旧gate用真实0.25倍率扩大对应墙钟窗口,
不代表任意调度延迟下均可送达。该轮还有一项NaN错过窗口,125/132通过,完整归档。最终受影响42项
三引擎定向复验通过后重跑全矩阵。未扩大超时、改变生产逻辑或删除最终断言。
- 后续源码132项通过,主构建三并发131/132通过:WebKit旧核心的reused弹幕未进入
beforeVisible,只有初始moving的Worker请求。queue与04及冻结源码的±0.1秒规则
相同;2倍速时窗口约100毫秒,但没有当时逐帧媒体读数,不能断言帧间隔是根因。
- 同一主构建、同一132项改为单并发后128通过、4失败,原两核心倍速复用例均通过。
新失败为两个初始媒体ready超时、一个context关闭超时、一个page创建超时及其
null page后续错误。完整报告保留;这些不是移动节点修复的红例,也不能证明
主机或WebKit自身是唯一原因。此后修复清理遗漏,新产物使用与CI一致的2并发
重新运行完整矩阵,retries仍为0,前述失败并未被删除或算作已修复。
- 移动节点修复后的源码137/138通过,唯一失败在新增清理例的MOVED出现之前。
清理例不负责固定时间窗口,把两个renderer资源例的起点明确设为ready,再要求
原生视频、真实Worker和可见DOM后执行清理;原生时间/倍速/轨道用例继续保留。
倍速用例额外代理原readys getter一次且原样返回,记录最多2000份真实媒体时间、
队列与ready样本,方便后续区分资格遗漏与渲染失败,不修改生产时间或轨道判断。
受影响18项定向验证通过后,重新运行三种产物完整414项,均通过。
机器记录、文件指纹、失败及最终报告见
[danmuku-resources-validation.json](../baselines/danmuku-resources-validation.json)。
首次三引擎失败完整归档,最终档案的截图附件保留原报告路径到archive目录的映射。
## 交接和回退
CLEANUP-01/HEATMAP-01按本步具体标准关闭。LOAD-01、完整TS/声明、真实长负载、
设备及发布前复盘仍归后续任务,不由本步通过替代。下一项06在提交核验后启动。
本步对应独立本地commit;若回退,整体revert该提交并同步任务/风险状态,不单独
恢复dist或只退资源模块。没有推送、标签或npm发布。
+4 -3
View File
@@ -4,7 +4,7 @@
基线:`40fcda6a37d0049d42e49c1e64e70d4fd9ba5f7f`。总任务 228 项,范围 22 个包及工作区/示例。
状态:todo 70 / doing 15 / blocked 0 / done 143 / deferred 0。风险 L/M/H 表示兼容风险,不表示工期。
状态:todo 69 / doing 15 / blocked 0 / done 144 / deferred 0。风险 L/M/H 表示兼容风险,不表示工期。
前置依赖是启动条件;验收是完成条件。任务可以继续拆分,但不能复用或悄悄删除旧 ID。
@@ -313,8 +313,8 @@
| PKG-DANMUKU-02 | artplayer-plugin-danmuku<br>建立弹幕算法与浏览器基线 | PKG-DANMUKU-01, ENG-05, ENG-08 | 密集/稀疏弹幕、过滤/异步输入、seek/倍率/重载测试 | 轨道选择、发射顺序、事件、内存和可视结果可重跑 | H | done |
| PKG-DANMUKU-03 | artplayer-plugin-danmuku<br>整理加载、解析与配置 | PKG-DANMUKU-02, CORE-08 | bilibili/input/parser/config 的分层与取消 | 旧格式、回调、过滤、追加/替换语义保持 | M | done |
| PKG-DANMUKU-04 | artplayer-plugin-danmuku<br>整理时钟、队列与轨道调度 | PKG-DANMUKU-03, CORE-10 | danmuku 调度器和确定性时钟测试 | seek/暂停/倍率/长时间运行无顺序和碰撞回归 | H | done |
| PKG-DANMUKU-05 | artplayer-plugin-danmuku<br>整理 DOM 渲染、设置、热力图与 worker | PKG-DANMUKU-04, CORE-14, CORE-18 | renderer/setting/heatmap/worker 职责及资源归属 | mount/icons/设置和 worker 协议保持,销毁无后台工作 | H | doing |
| PKG-DANMUKU-06 | artplayer-plugin-danmuku<br>迁移 TS 与公开声明 | PKG-DANMUKU-05, ENG-04, ENG-06 | 自有模块、worker 消息、option/item/result 类型 | 旧参数、扩展字段和事件消费通过,vendored 边界清楚 | H | todo |
| PKG-DANMUKU-05 | artplayer-plugin-danmuku<br>整理 DOM 渲染、设置、热力图与 worker | PKG-DANMUKU-04, CORE-14, CORE-18 | renderer/setting/heatmap/worker 职责及资源归属 | mount/icons/设置和 worker 协议保持,销毁无后台工作 | H | done |
| PKG-DANMUKU-06 | artplayer-plugin-danmuku<br>迁移 TS 与公开声明 | PKG-DANMUKU-05, ENG-04, ENG-06 | 自有模块、worker 消息、option/item/result 类型 | 旧参数、扩展字段和事件消费通过,vendored 边界清楚 | H | doing |
| PKG-DANMUKU-07 | artplayer-plugin-danmuku<br>弹幕能力稳定性验收 | PKG-DANMUKU-06 | 负载/渲染/资源对比及 mask 可依赖的稳定边界 | 在试点核心中旧插件 API 与关键帧路径通过 | H | todo |
| PKG-DANMUKU-08 | artplayer-plugin-danmuku<br>完成新旧核心与组合验收 | PKG-DANMUKU-07, CORE-22 | 最终核心/旧核心、mask/fullscreen/PiP 组合报告 | 性能无未解释退化,反复装卸无累计资源 | H | todo |
| PKG-DANMUKU-09 | artplayer-plugin-danmuku<br>完成分发、示例与文档 | PKG-DANMUKU-08, ENG-07 | danmuku.js、README、声明、worker 与产物 | tarball 和静态 icons 等旧调用通过,有独立回退版本 | H | todo |
@@ -557,6 +557,7 @@
- PKG-DANMUKU-02: [记录](changes/2026-09-13-PKG-DANMUKU-02-controlled-failures.md) [记录](baselines/danmuku-failures-validation.json) [记录](changes/2026-09-13-PKG-DANMUKU-02-browser-baseline.md) [记录](baselines/danmuku-browser-validation.json)
- PKG-DANMUKU-03: [记录](changes/2026-09-13-PKG-DANMUKU-03-input.md) [记录](baselines/danmuku-input-validation.json)
- PKG-DANMUKU-04: [记录](changes/2026-09-13-PKG-DANMUKU-04-scheduler.md) [记录](baselines/danmuku-scheduler-validation.json)
- PKG-DANMUKU-05: [记录](changes/2026-09-13-PKG-DANMUKU-05-resources.md) [记录](baselines/danmuku-resources-validation.json)
- PKG-CANVAS-01: [记录](changes/2026-09-12-PKG-CANVAS-01-contract.md) [记录](baselines/canvas-contract.md) [记录](baselines/canvas-release.json) [记录](canvas-validation.md) [记录](baselines/canvas-contract-validation.json)
- PKG-CANVAS-02: [记录](changes/2026-09-12-PKG-CANVAS-02-tests.md) [记录](baselines/canvas-behavior-validation.json) [记录](canvas-validation.md)
- PKG-CANVAS-03: [记录](changes/2026-09-12-PKG-CANVAS-03-lifecycle.md) [记录](baselines/canvas-lifecycle-validation.json) [记录](canvas-validation.md)
+12
View File
@@ -1,5 +1,17 @@
# 进度与证据
## PKG-DANMUKU-05 渲染、设置与热力图完成
拆renderer、Setting模板/滑块/发送/资源/全局样式和heatmap采样/几何/生命周期。
修复外部DOM、锁计时器、订阅与节点清理、初始化回滚及窄热力图卡死,保留共享宿主
用户写入、原points mutation、首实例SVG钩子与合法大数据。源码/main/legacy各159项
联合测试,完整test:danmuku245项、三格式×138共414原生浏览器项通过;冻结安装、
严格工具链、完整类型检查和正常构建通过。内置浏览器完成现有docs示例播放/暂停/发送。
关闭CLEANUP-01/HEATMAP-01,见[变更](changes/2026-09-13-PKG-DANMUKU-05-resources.md)及[机器证据](baselines/danmuku-resources-validation.json)。
228项:144 done、15 doing、69 todo;06进入完整TS。
真实长负载、发布前复盘仍待对应任务;无推送或发布。
## PKG-DANMUKU-04 时钟、队列与轨道调度完成
拆分scheduler/queue/worker-client,修复多RAF、同毫秒请求串线、取消后续写、
+3 -2
View File
@@ -230,10 +230,11 @@
| DANMUKU-TYPE-01 | open / 已复现 | Danmuku historical declared results, optional mount and initial Promise input disagree with runtime | PKG-DANMUKU-03, PKG-DANMUKU-06 |
| DANMUKU-INPUT-01 | resolved / 已复现 | Danmuku replaces time zero with current time plus 0.5 and mutates supplied input objects | PKG-DANMUKU-02, PKG-DANMUKU-03 |
| DANMUKU-CONFIG-01 | resolved / 已复现 | Danmuku JSON configuration comparison ignores a replacement filter function | PKG-DANMUKU-02, PKG-DANMUKU-03 |
| DANMUKU-CLEANUP-01 | open / 已复现 | Danmuku removes a different resize callback and retains the settings lock timer on destroy | PKG-DANMUKU-02, PKG-DANMUKU-05 |
| DANMUKU-CLEANUP-01 | resolved / 已复现 | Danmuku removes a different resize callback and retains the settings lock timer on destroy | PKG-DANMUKU-02, PKG-DANMUKU-05 |
| DANMUKU-TYPE-02 | open / 源码/产物事实 | Danmuku id, icons, Slider steps, heatmap points and partial configuration drift from declarations | PKG-DANMUKU-05, PKG-DANMUKU-06 |
| DANMUKU-ASYNC-01 | resolved / 已复现 | Danmuku asynchronous input, worker replies and pending visibility have unverified failure and cancellation paths | PKG-DANMUKU-02, PKG-DANMUKU-03, PKG-DANMUKU-04, PKG-DANMUKU-05 |
| DANMUKU-HEATMAP-01 | open / 已复现 | Danmuku heatmap sampling can become zero and points/instance ownership need browser validation | PKG-DANMUKU-02, PKG-DANMUKU-05 |
| DANMUKU-HEATMAP-01 | resolved / 已复现 | Danmuku heatmap sampling can become zero and points/instance ownership need browser validation | PKG-DANMUKU-02, PKG-DANMUKU-05 |
| DANMUKU-SOURCE-01 | open / 已复现 | Danmuku registry Git associations differ from releases and static icon provenance remains incomplete | PKG-DANMUKU-09 |
| DANMUKU-TRACK-01 | resolved / 已复现 | Native simultaneous fixed Danmuku comments can overlap with duplicate start loops and repeated Worker IDs | PKG-DANMUKU-04, PKG-DANMUKU-05, PKG-DANMUKU-07 |
| DANMUKU-INPUT-02 | resolved / 已复现 | Intermediate explicit-zero correction regressed accepted NaN timestamp fallback | PKG-DANMUKU-04 |
| DANMUKU-LOAD-01 | open / 待取证 | Native lifecycle fixtures sometimes miss timestamp eligibility during concurrent workload; real frame/window behavior needs load evidence | PKG-DANMUKU-07 |
+42 -6
View File
@@ -5094,7 +5094,7 @@
"id": "DANMUKU-CLEANUP-01",
"title": "Danmuku removes a different resize callback and retains the settings lock timer on destroy",
"confirmation": "reproduced",
"status": "open",
"status": "resolved",
"owners": [
"PKG-DANMUKU-02",
"PKG-DANMUKU-05"
@@ -5108,10 +5108,20 @@
"refactor/changes/2026-09-13-PKG-DANMUKU-03-input.md",
"refactor/baselines/danmuku-input-validation.json",
"refactor/changes/2026-09-13-PKG-DANMUKU-04-scheduler.md",
"refactor/baselines/danmuku-scheduler-validation.json"
"refactor/baselines/danmuku-scheduler-validation.json",
"refactor/changes/2026-09-13-PKG-DANMUKU-05-resources.md",
"refactor/baselines/danmuku-resources-validation.json"
],
"compatibleResolution": "Track and release exact subscription and timer ownership across settings, renderer and instances.",
"closureCriteria": "Repeated lifecycle and pending settings actions leave no owned subscriptions, timers or late DOM writes."
"closureCriteria": "Repeated lifecycle and pending settings actions leave no owned subscriptions, timers or late DOM writes.",
"resolutionEvidence": [
"refactor/changes/2026-09-13-PKG-DANMUKU-05-resources.md",
"refactor/baselines/danmuku-resources-validation.json",
"test/danmuku-setting.test.js",
"test/danmuku-heatmap.test.js",
"test/browser/danmuku-resources.spec.js"
],
"resolutionRationale": "Exact subscriptions/proxy registry entries, send countdowns, external settings and owned renderer nodes are released; stale sends are cancelled and shared host values restored conditionally. Native two-core source/main/legacy matrices and real docs smoke passed."
},
{
"id": "DANMUKU-TYPE-02",
@@ -5169,7 +5179,7 @@
"id": "DANMUKU-HEATMAP-01",
"title": "Danmuku heatmap sampling can become zero and points/instance ownership need browser validation",
"confirmation": "reproduced",
"status": "open",
"status": "resolved",
"owners": [
"PKG-DANMUKU-02",
"PKG-DANMUKU-05"
@@ -5181,10 +5191,20 @@
"refactor/baselines/danmuku-failures-validation.json",
"test/danmuku-failures.test.js",
"refactor/changes/2026-09-13-PKG-DANMUKU-02-browser-baseline.md",
"refactor/baselines/danmuku-browser-validation.json"
"refactor/baselines/danmuku-browser-validation.json",
"refactor/changes/2026-09-13-PKG-DANMUKU-05-resources.md",
"refactor/baselines/danmuku-resources-validation.json"
],
"compatibleResolution": "Use isolated timeout-protected reproduction for narrow dimensions, then define finite sampling and per-instance rendering.",
"closureCriteria": "Narrow widths terminate, points/config behavior is explicit and multiple SVG/control instances remain independent."
"closureCriteria": "Narrow widths terminate, points/config behavior is explicit and multiple SVG/control instances remain independent.",
"resolutionEvidence": [
"refactor/changes/2026-09-13-PKG-DANMUKU-05-resources.md",
"refactor/baselines/danmuku-resources-validation.json",
"test/danmuku-setting.test.js",
"test/danmuku-heatmap.test.js",
"test/browser/danmuku-resources.spec.js"
],
"resolutionRationale": "Narrow/invalid sampling terminates; exact historical curves and nested point mutation retained; valid large inputs are not capped arbitrarily. Native multi-instance and repeated-bundle gradient isolation preserves the first legacy ID and independent progress/control cleanup."
},
{
"id": "DANMUKU-SOURCE-01",
@@ -5252,6 +5272,22 @@
"test/browser/danmuku-scheduler.spec.js"
],
"resolutionRationale": "Historical source/main/legacy establish old behavior; source/main/legacy final input and native matrices confirm the one-condition correction. Task03 frozen evidence is preserved."
},
{
"id": "DANMUKU-LOAD-01",
"title": "Native lifecycle fixtures sometimes miss timestamp eligibility during concurrent workload; real frame/window behavior needs load evidence",
"confirmation": "unverified",
"status": "open",
"owners": [
"PKG-DANMUKU-07"
],
"evidence": [
"refactor/changes/2026-09-13-PKG-DANMUKU-05-resources.md",
"refactor/baselines/danmuku-resources-validation.json",
"test/browser/danmuku-scheduler.spec.js"
],
"compatibleResolution": "Capture native RAF/media-time gaps and scheduled/eligible/visible item counts under realistic load before deciding whether the old plus/minus 0.1 second eligibility rule needs a compatible correction.",
"closureCriteria": "Real load runs explain missing scheduled items with frame and media evidence, and any confirmed implementation defect has a regression and compatible fix; seeding ready in lifecycle fixtures is not closure evidence."
}
]
}
+6 -3
View File
@@ -3341,11 +3341,14 @@
"CORE-14",
"CORE-18"
],
"status": "doing",
"status": "done",
"risk": "H",
"deliverable": "renderer/setting/heatmap/worker 职责及资源归属",
"acceptance": "mount/icons/设置和 worker 协议保持,销毁无后台工作",
"evidence": []
"evidence": [
"changes/2026-09-13-PKG-DANMUKU-05-resources.md",
"baselines/danmuku-resources-validation.json"
]
},
{
"id": "PKG-DANMUKU-06",
@@ -3359,7 +3362,7 @@
"ENG-04",
"ENG-06"
],
"status": "todo",
"status": "doing",
"risk": "H",
"deliverable": "自有模块、worker 消息、option/item/result 类型",
"acceptance": "旧参数、扩展字段和事件消费通过,vendored 边界清楚",