test(danmuku): [PKG-DANMUKU-07] verify native load and shared layer stability

This commit is contained in:
Harvey Zhao committed 2026-09-13 23:16:04 +08:00
1 parent 4f559cb31d
commit 00e81309ca
14 files changed
+6724 -11

No files matched your search

+4 -1
View File
@@ -53,7 +53,10 @@
`setBackend` fulfilled false 视为已执行 fallback。
registrar 捕获 `art.template.$video/$danmuku`,订阅 ready→start、destroy→stop。
必须在 Danmuku 插件建立 `$danmuku` 后注册;demo 正是先 Danmuku 再 Mask。
需要核心模板已经提供 `$danmuku/$video`;demo 使用先 Danmuku 再 Mask 的顺序。
2026-09-13(PKG-DANMUKU-07)纠正初始记录:`$danmuku` 由核心模板创建,
不是 Danmuku 插件创建,因此 demo 顺序本身不构成 Mask 对 Danmuku 注册的硬依赖。
Mask 源码不读取 Danmuku 队列、owner 或插件事件;完整模型组合仍待 Mask 验收。
start 建立 2D canvas 并设置 `$danmuku.style`:maskMode=alpha、maskSize=contain、
maskRepeat=no-repeat、backgroundSize=contain、backgroundRepeat=no-repeat。
每轮以视频固有尺寸推理,白色前景/黑色背景生成 binary mask,drawMask 后将 RGB
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,66 @@
# PKG-DANMUKU-07 弹幕稳定性与共享层边界
已完成本任务限定的验收,任务及提交状态以tasks.json和Git为准。此项对12后的生产
实现增加原生负载和资源验收,没有改变运行时、声明、依赖、版本或构建内容。
## 验收范围
- 候选核心中比较固定npm5.3.0插件与候选源码,三引擎,每秒2和20条,各三轮
14秒真实媒体播放。每轮追加12秒的时间戳序列,三轮总计72/720条;其余时间
让弹幕自然显示和到期。保留真实RAF、视频时钟、Worker与原始readys getter。
- 候选逐项检查采样/显示无丢失,三轮总显示和回收均恰好一次;队列追加语义、
每条对象只属于一个对应状态池、空闲池唯一性、根层节点和空闲池一致均受断言保护。
包装原始节点getter只记录身份,确认实际重复使用旧节点,并且有空闲节点时
不绕过池分配新节点;Worker必须存在且唯一,正常请求全部回复,销毁恰好一次。
- 旧插件结果保留为对照观察,没有把其可能的历史缺陷豁免用于候选断言。
每轮帧间隔单独统计;包含暂停/加载转换的总采样间隔另列,不能当纯播放卡顿。
可选performance.memory是未强制GC的读数,不能证明泄漏或作跨引擎内存排名。
- 两核心、三引擎运行已有资源用例:共享挂载、初始化回滚、发送取消/锁、原始
错误、destroy(false)、替换加载移除被移动的节点、热图实例隔离。
- 新增两核心的CSS mask边界用例:注册前就取得核心根层,以固定内联SVG mask
验证emit/reset/无参替换load/hide/show/destroy(false)中的层引用和样式保持,
销毁后两帧没有晚请求和新子节点。此用例设置资源测试的ready前置状态、采用
原生0.25播放速率,不能当时间戳负载证据;负载用例没有这些设置。
## 问题处置与兼容性
早期原生时间窗口诊断区分了两个来源:800ms主线程完全阻塞,及600ms用户异步
回调使旧调度停止采样。11独立修复隐藏Worker等待吞掉显示寿命;12独立修复异步
放置期间的采样和到期维护。07继续检查这些修复后的实际负载及资源状态。
没有把公开±0.1秒窗口改成无限追赶,因此完全阻塞时未被采样的时间点仍可错过。
本轮首个测试版本错误地把`load(rows)`当作替换,第二轮队列断言收到48/480而
错误预期24/240。核实原实现后修正累计队列预期,当轮显示数仍精确24/240;没有
修改生产语义。初步12项通过后,经独立审查补足Worker非空、节点身份复用、
逐条状态归属和跨轮恰好一次的断言,最终需按补强后的文件重新验证。
Mask仅依赖核心提供的video/弹幕根层及ready/destroy,不读取弹幕队列、Owner
或插件事件。旧契约文档误称根层由Danmuku建立,已依据核心模板纠正并注明日期。
固定发布归档和生产Mask源码未改。Mask自身晚推理复活RAF、模型dispose、并发
start、模型和完整组合问题仍由Mask迁移任务处理,不能从本CSS测试判定通过。
## 维护与重跑
```sh
yarn test:browser test/browser/danmuku-stability.spec.js test/browser/danmuku-mask-boundary.spec.js test/browser/danmuku-resources.spec.js --workers=2
```
负载测试的90秒单例deadline来自三轮42秒媒体预算及设置/销毁开销;没有扩大
已有短用例超时。每次运行必须等待进程终态,归档report/results,再运行另一格式。
正常来源是当前源码UMD;两个新用例均支持ARTPLAYER_DANMUKU_ARTIFACT。
包内ARCHITECTURE.md与refactor/danmuku-stability.md记录根层归属、诊断及限制。
07未修改生产,因此复用12已记录的264项源码/136项产物单测、严格类型/构建,及
其异步/几何/生命周期验证;不声称这些由本次持续负载套件重新完成。
08完整组合、09最终分发、真实Mask模型/设备以及全项目发布复盘继续保留。
回退本任务只撤销测试和文档,不应回退11/12已交付修复。
## 最终结果
补强后的66项浏览器检查全部通过(12项负载、6项CSS边界、48项资源),0重试、
0跳过。每个负载用例完成三轮42秒原生媒体推进,候选两档各72/720条均完整且
只显示/回收一次。精确节点复用、堆读数和帧间隔见
[机器证据](../baselines/danmuku-stability-validation.json)。
新测试lint通过;影响分析检查通过,保留Danmuku/Mask组合验证边,仅纠正其
“Danmuku创建根层”的错误原因,不降低CI范围。测试由现有Playwright目录自动发现。
未运行远端CI、未推送或发布。
+70
View File
@@ -0,0 +1,70 @@
# PKG-DANMUKU-07 稳定性工作记录
本任务已在12后的运行时完成下述限定范围验收,任务与提交状态以tasks.json及Git为准。
06类型检查、11/12修复与本任务证据分别维护;真实模型、完整组合和发布验收仍待后续任务。
## 已执行的时间窗口诊断
`test/browser/danmuku-timing-diagnostic.spec.js`在候选核心中比较实际npm5.3.0插件与
06候选源码,使用本地90秒视频的短片段、原生RAF/媒体时钟和真实Worker。独立RAF
观察与实际readys getter采样分别记录;getter只包装读取,不修改返回数组或状态。
每例3条弹幕,后置sentinel证明间隔后仍能正常发送。12项诊断通过意味着取证完成,
不代表漏掉弹幕的结果可以作为稳定性通过。
| 场景 | Chromium | Firefox | Windows WebKit | 新旧共同结果 |
| --- | --- | --- | --- | --- |
| 注入800ms主线程工作 | 最大媒体帧间隔约800ms | 约777–809ms | 约838–856ms | 前两条未进入任何readys采样,sentinel显示 |
| beforeVisible等待600ms | 原生帧间隔约19–21ms,采样间隔616–618ms | 帧44ms,采样583–609ms | 帧63–64ms,采样622–647ms | 第一条与sentinel显示,中间条未采样 |
这解释了两种不同来源:前者浏览器主线程无法及时调度,后者浏览器仍在出帧,但
插件等待当前异步准备完成而不再读取新的候选窗口。±0.1秒和串行回调都有明确
历史语义;后续方案必须比较seek、hide/show、stop/start和false重试边界,不能
直接改成无限追赶或并行回调。当前不据此声称全部真实负载问题已解决。
报告位于refactor/.cache/danmuku07-timing-diagnostic.json,日志及附件保留同名前缀。
候选是11计时修复之前的06源码,具体构建SHA在每项danmuku-timing-observation中;
后续变更需说明哪些观察仍适用,不把旧报告冒充新提交的验证。
## 当前下一步
以下为本轮执行入口的历史清单,现已通过最终66项原生用例落实本任务范围。
下一实施阶段为08组合或其他已就绪包任务;09分发和真实Mask模型/设备仍不能据此关闭。
1. 11计时修复和12采样修复已分别提交并核验;当前HEAD为
`4f559cb31d6b69a37439c6db2d32ca28ae5c78f3`,恢复本任务。
12源码/main/legacy各102项浏览器通过,慢回调中间行已恢复;CPU完全阻塞
的未采样窗口仍保留。见[12证据](baselines/danmuku-frame-sampling-validation.json)。
2. 对实际持续播放记录scheduled、readys、callback、placed、visible、recycled及
原生RAF/媒体间隔,区分false、拒绝、轨道满、取消和错过采样。
3. 比较正常密度、密集队列和连续生命周期后的节点池、Worker、监听器与计时器。
已有受控三小时快进只证明离散状态,不是真实三小时播放或内存测量。
4. 根据证据决定是否需要兼容内部修复,并为每个独立修复保留任务和commit。
5. 明确Mask可依赖的当前队列/DOM/事件边界,再交付07验收与后续08组合矩阵。
不增加任意弹幕上限,不通过修改媒体时钟、预置ready或放宽断言伪造负载通过。
## 本轮新增的持续播放与边界取证
`test/browser/danmuku-stability.spec.js` 使用候选核心、实际npm5.3.0/候选插件、
原生视频/RAF/Worker,每秒2或20条,各三轮14秒实际媒体推进。每轮追加12秒
的时间戳序列,余下时间用于自然显示和回收;逐条记录采样/显示/回收,同时记录
状态池、节点/空闲池、真实帧和可选未强制GC的堆内存读数。不是三小时耐久测试,
也不把不同浏览器的performance.memory当作可比的泄漏证明。
首轮Chromium两个用例因测试误把`load(rows)`当作替换,在第二轮队列断言失败:
收到48/480,错误预期24/240。核对运行实现后按既有追加契约修正为累计队列数,
当轮显示数量仍严格断言24/240;没有改变生产API。失败报告与trace保留在
`refactor/.cache/danmuku07-stability-first.json`及同前缀results中。
Mask静态审查已确认其直接依赖只有核心video/root层/ready/destroy,未读取弹幕
队列或Owner。已纠正旧契约对根层创建归属的错误描述;核心模板及节点绑定为依据。
后续CSS mask边界测试明确不加载真实模型,不代替Mask03/05的候选生命周期与组合验收。
最终补强了非空Worker、实际节点复用、每条状态归属和跨轮显示/回收恰好一次检查。
12负载、6共享mask层、48资源测试共66项在三引擎全部通过,0重试/跳过。
见[变更记录](changes/2026-09-13-PKG-DANMUKU-07-stability.md)和
[机器证据](baselines/danmuku-stability-validation.json)。
本次候选每秒2条用例三轮72条只分配3个节点、实际复用69次;每秒20条三轮720条
分配21–22个节点、复用698–699次。旧版对应分配6及24–25个节点。两者该正常
同步回调负载下都完整显示;差异是本次原生样本观察,不是通用吞吐或长期内存承诺。
+1 -1
View File
@@ -121,7 +121,7 @@
{
"dependency": "artplayer-plugin-danmuku",
"consumer": "artplayer-plugin-danmuku-mask",
"reason": "Mask renders into the $danmuku element supplied by the danmuku plugin",
"reason": "Mask and Danmuku share the core-owned $danmuku layer; retain combination validation for root identity, styles and lifecycle",
"evidence": [
"packages/artplayer-plugin-danmuku-mask/src/index.js",
"docs/assets/example/danmuku.mask.js"
+3 -2
View File
@@ -4,7 +4,7 @@
基线:`40fcda6a37d0049d42e49c1e64e70d4fd9ba5f7f`。总任务 231 项,范围 22 个包及工作区/示例。
状态:todo 68 / doing 15 / blocked 0 / done 148 / deferred 0。风险 L/M/H 表示兼容风险,不表示工期。
状态:todo 68 / doing 14 / blocked 0 / done 149 / deferred 0。风险 L/M/H 表示兼容风险,不表示工期。
前置依赖是启动条件;验收是完成条件。任务可以继续拆分,但不能复用或悄悄删除旧 ID。
@@ -315,7 +315,7 @@
| 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 | done |
| PKG-DANMUKU-06 | artplayer-plugin-danmuku<br>迁移 TS 与公开声明 | PKG-DANMUKU-05, ENG-04, ENG-06 | 自有模块、worker 消息、option/item/result 类型 | 旧参数、扩展字段和事件消费通过,vendored 边界清楚 | H | done |
| PKG-DANMUKU-07 | artplayer-plugin-danmuku<br>弹幕能力稳定性验收 | PKG-DANMUKU-06, PKG-DANMUKU-10, PKG-DANMUKU-11, PKG-DANMUKU-12 | 负载/渲染/资源对比及 mask 可依赖的稳定边界 | 在试点核心中旧插件 API 与关键帧路径通过 | H | doing |
| PKG-DANMUKU-07 | artplayer-plugin-danmuku<br>弹幕能力稳定性验收 | PKG-DANMUKU-06, PKG-DANMUKU-10, PKG-DANMUKU-11, PKG-DANMUKU-12 | 负载/渲染/资源对比及 mask 可依赖的稳定边界 | 在试点核心中旧插件 API 与关键帧路径通过 | H | done |
| 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 |
| PKG-DANMUKU-10 | artplayer-plugin-danmuku<br>修复 issue958 密集热力图过高与曲线裁平 | PKG-DANMUKU-05 | 自动密度缩放与曲线边界、历史自定义坐标兼容及真实浏览器红绿证据 | 16000条三种分布在两核心三引擎和source/main/legacy不遮挡;显式轴和自定义points保持旧解释,有单独commit | M | done |
@@ -562,6 +562,7 @@
- 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-DANMUKU-06: [记录](changes/2026-09-13-PKG-DANMUKU-06-types.md) [记录](baselines/danmuku-types-validation.json)
- PKG-DANMUKU-07: [记录](changes/2026-09-13-PKG-DANMUKU-07-stability.md) [记录](baselines/danmuku-stability-validation.json) [记录](danmuku-stability.md)
- 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)
+14
View File
@@ -1,5 +1,19 @@
# 进度与证据
## PKG-DANMUKU-07 弹幕稳定性阶段验收完成
12后的源码在三引擎完成新旧插件两档负载对照,每例三轮42秒原生播放;候选
72/720条全部采样、显示并回收一次,真实节点复用、状态池唯一归属和Worker清理通过。
两核心共享CSS mask根层与已有资源回归通过;最终12+6+48共66项,0重试/跳过。
首轮错误测试把load(rows)当替换,修正为历史追加契约并保留失败报告;独立审查
补足复用与跨轮重复断言。Mask不依赖队列,根层属于核心;纠正文档和影响映射原因,
保留组合CI范围。lint及影响检查通过,没有生产/声明/依赖变化,复用12的相关验证。
见[变更](changes/2026-09-13-PKG-DANMUKU-07-stability.md)和
[证据](baselines/danmuku-stability-validation.json)。DANMUKU-LOAD-01按已解释来源及
11/12独立修复闭环;CPU阻塞下旧窗口不追赶的边界明确保留,不声称无条件无漏弹幕。
231项:149 done、14 doing、68 todo。08完整组合、09分发、真实Mask模型和设备/
发布复盘继续;独立本地提交,不推送、不发布。
## PKG-DANMUKU-12 持续采样与串行放置完成
异步beforeVisible/Worker等待期间继续原生RAF采样和可见寿命维护,以内部身份
+1 -1
View File
@@ -237,7 +237,7 @@
| 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 |
| DANMUKU-LOAD-01 | resolved / 已复现 | Native lifecycle fixtures sometimes miss timestamp eligibility during concurrent workload; real frame/window behavior needs load evidence | PKG-DANMUKU-07 |
| DANMUKU-HEATMAP-02 | resolved / 已复现 | Issue958 dense automatic heatmaps exceed the fixed Y domain and flatten across video | PKG-DANMUKU-10 |
| DANMUKU-TIMING-01 | resolved / 已复现 | Hidden Worker wait is deducted from visible lifetime and can recycle a comment immediately after visible | PKG-DANMUKU-11 |
| DANMUKU-SAMPLING-01 | resolved / 已复现 | Serial asynchronous placement stops native frame eligibility sampling and delays existing visible expiry | PKG-DANMUKU-12 |
+13 -4
View File
@@ -5290,18 +5290,27 @@
{
"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",
"confirmation": "reproduced",
"status": "resolved",
"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"
"test/browser/danmuku-scheduler.spec.js",
"refactor/baselines/danmuku-stability-validation.json",
"refactor/baselines/danmuku-frame-sampling-validation.json"
],
"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."
"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.",
"resolutionEvidence": [
"refactor/baselines/danmuku-stability-validation.json",
"refactor/changes/2026-09-13-PKG-DANMUKU-07-stability.md",
"refactor/baselines/danmuku-frame-sampling-validation.json",
"refactor/baselines/danmuku-lifetime-validation.json"
],
"resolutionRationale": "Native timing evidence distinguishes unobserved CPU-blocked windows from asynchronous scheduler starvation. Tasks 11/12 fix the reproduced implementation defects. Final three-engine real-load runs keep candidate scheduled rows observed/displayed/recycled exactly once, with actual node reuse and state/Worker ownership; unchanged historical CPU-gap semantics and full model/device/release scope remain explicit."
},
{
"id": "DANMUKU-HEATMAP-02",
+6 -2
View File
@@ -3384,11 +3384,15 @@
"PKG-DANMUKU-11",
"PKG-DANMUKU-12"
],
"status": "doing",
"status": "done",
"risk": "H",
"deliverable": "负载/渲染/资源对比及 mask 可依赖的稳定边界",
"acceptance": "在试点核心中旧插件 API 与关键帧路径通过",
"evidence": []
"evidence": [
"changes/2026-09-13-PKG-DANMUKU-07-stability.md",
"baselines/danmuku-stability-validation.json",
"danmuku-stability.md"
]
},
{
"id": "PKG-DANMUKU-08",