diff --git a/refactor/baselines/README.md b/refactor/baselines/README.md index 6e913ae81..99a228d2e 100644 --- a/refactor/baselines/README.md +++ b/refactor/baselines/README.md @@ -44,3 +44,7 @@ BASE-04 已在内置浏览器完成两轮 16 项 DOM/样式/实际输入断言 ## 分发、类型与 SSR 消费 BASE-05 的 [覆盖/复跑/历史诊断](consumer-coverage.md) 包含 18 项 Node runtime、16 项严格 TS 场景和浏览器两轮各 5 项 SSR 检查。[消费者](consumers.json)、[SSR](ssr.json)、[22 包资源](distribution.json) 分别记录已发布内容与工作区观察。8 项类型历史失败保持显式,不能计作候选通过。 + +## 性能和资源 + +BASE-06 保存两轮交错计时与独立资源诊断,见 [采样/阈值/范围](performance-coverage.md)、[原始报告](performance.json) 和 [压缩体积](sizes.json)。销毁后的延迟 resize/notice 工作已登记,不能把基本清理通过当成无内存泄漏证明;本任务没有优化收益声明。 diff --git a/refactor/baselines/performance-coverage.md b/refactor/baselines/performance-coverage.md new file mode 100644 index 000000000..0b761cc9a --- /dev/null +++ b/refactor/baselines/performance-coverage.md @@ -0,0 +1,73 @@ +# 性能与资源基线 + +BASE-06 使用固定发布 core 5.4.0 / chapter 1.1.0、本地 video.mp4 和 640x360 容器。两次独立页面重载,每次 12 个计时样本和 6 个资源探针;保留原始数据、预热标记和来源,见 [performance.json](performance.json)。没有修改生产实现,本任务不声称任何优化收益。 + +## 环境与采样 + +- Codex 内置浏览器,UA Chrome 152.0.0.0 / Windows,viewport 890x1272,devicePixelRatio=1,全程 visible,无 visibilitychange。 +- 浏览器报告 hardwareConcurrency=12、deviceMemory=32;这些是浏览器暴露值。测量后独立 Windows CIM 查询为 i5-12400F / 6 物理核心 / 12 逻辑线程 / 31.8 GiB 内存,记录在 hostContext,不将浏览器字段当硬件容量证明。 +- 发布 JS、夹具 LF 指纹和媒体 SHA-256 均绑定报告;固定本地服务返回 no-store,但未强制清空操作系统/解码器/连接缓存,不能称严格冷启动。其他应用负载、CPU 电源/温度和浏览器调度未锁定。 +- 每轮 core/chapter 交错执行,各 1 个预热、5 个计时样本;原始预热也保留。构造同步耗时、构造到 ready、play Promise 兑现、destroy 同步耗时分别测量。ready 通过 RAF 轮询已就绪状态,包含约一帧的观察量化和本地媒体初始化,不能称精确解码延迟。 +- 每个样本真实播放 currentTime 至少前进 0.15 秒,然后暂停、销毁;不通过固定 sleep 假装媒体就绪。没有测完整片段播放、FPS、 dropped frames、seek 热路径、首个呈现帧或下载耗时。 + +## 两轮计时结果 + +以下均为各 5 个非预热样本的中位数,单位 ms;完整 min/median/max 在报告中。样本量不足以报告有意义的尾部百分位或置信收益。 + +| 配置/轮次 | constructor | ready | play Promise | destroy | +| --- | ---: | ---: | ---: | ---: | +| core 第一轮 | 5.60 | 30.20 | 3.00 | 3.00 | +| chapter 第一轮 | 5.70 | 29.80 | 3.40 | 3.10 | +| core 第二轮 | 4.10 | 12.80 | 3.10 | 2.80 | +| chapter 第二轮 | 5.00 | 14.50 | 1.40 | 3.20 | + +代码完全相同,ready 中位数仍明显变化,说明一次快慢差异不足以证明优化。后续候选须在相同浏览器/设备/viewport/样本/配置中交错旧新运行,至少三组配对复测后评估,不拿这张旧表与不同机器/浏览器直接比较。 + +## 资源观察 + +计时样本不替换定时器。资源探针另行临时追踪 window timeout/interval/RAF,并显式启用 USE_RAF=true;默认计时保持发布默认 USE_RAF=false。探针保留原生回调 this、参数、句柄和取消行为,但任何 instrumentation 仍可能扰动时序,因此资源探针的耗时不纳入性能比较。 + +每轮资源 probe 运行 core/chapter 各三次:实际播放至至少两个 raf 事件、开启 notice、触发一个自定义代理事件,以及受控的 synthetic window resize 后立即 destroy。350ms 是销毁后观察窗口,不是等待媒体加载的固定延迟。 + +| 观察面 | 两轮实际结果 | 判断界限 | +| --- | --- | --- | +| 计时样本 DOM / 实例 / proxy 清理 Set | 每次挂载 core 113 节点、chapter 125 节点;57 个代理清理项;销毁后均为 0 | 数量是本配置的观察,不是必须永远固定的内部结构;Set 为内部账本,不等同全浏览器原生监听器统计 | +| video | 每次销毁后 paused=true、src 属性移除 | 未证明网络连接、解码器、GPU 内存即时释放 | +| 资源探针自定义代理 | 销毁前收到一次,销毁后再次 dispatch 不增加调用 | 真实 DOM 事件分发但为受控 synthetic 事件,不冒充用户输入 | +| RAF | 销毁前至少 2 次;销毁后 0 次 | 检查 opt-in USE_RAF 路径,不等于所有插件的动画循环通过 | +| pending resize / notice | 每次销毁后仍有 200ms timeout;它执行一次 resize,随后创建新的 2000ms notice timeout;350ms 后仍在记录中 | BASE-PERF-01,见下节;不是已经修复或永久泄漏证明 | + +两轮六组资源状态相同,errors/unhandled 与浏览器 error/warn 日志为空,最终 Artplayer.instances=0。探针先保存未清资源,再用原生取消函数清理其追踪到的剩余句柄并恢复 API;**此额外清理不能算作播放器自己的清理成功**。追踪器本身会临时持有回调/句柄,未进行 heap snapshot、强制 GC、detached-node 可达性或进程 RSS 测量,不能给出“无内存泄漏”结论。 + +### BASE-PERF-01:销毁后的 resize 工作 + +受控 window resize 在 destroy 前安排 debounce,destroy 清掉 DOM 代理、现有 Info/Notice timer 和 RAF,但没有取消该 debounce。晚到回调再次 emit resize,aspectRatio setter 又安排 notice timeout。当前源码 resizeInit、utils/time、aspectRatioMix 与发布行为一致;CORE-17 负责取消/晚到事件,关联 CORE-04 生命周期和 CORE-18 notice 防线。 + +后续应增加候选正向断言:销毁后没有该 resize 回调及新通知计时器,同时保持正常 resize 时序和公开快捷键。不要要求候选继续满足历史异常 profile,也不要只延长等待至 timer 自然结束来掩盖失去生命周期归属的问题。旧实现的现象仅在此有界窗口确认,不能直接断言永久保留内存。 + +## 包体积与审查阈值 + +[sizes.json](sizes.json) 分别保存 28 个真实发布 JS 文件和 85 个工作区 JS 文件的 raw/gzip9/Brotli6 字节数。工作区覆盖 21 库并匹配 BASE-05 的历史观察哈希,可能包含陈旧 dist,不能当作 21 包的真实 npm 版本。文档站没有库 bundle 入口,其站点体积由 SITE/ENG-08 单独测量。压缩使用固定 Node 24.21.0 及记录的 zlib/Brotli 版本,单文件独立压缩不是生产 HTTP 实际传输量或安装后大小。 + +| 发布主文件 | raw bytes | gzip level 9 | Brotli quality 6 | +| --- | ---: | ---: | ---: | +| core .js | 134037 | 35486 | 32533 | +| core .legacy.js | 135748 | 36021 | 33045 | +| core .mjs | 208826 | 43868 | 40443 | +| chapter .js / .legacy.js,各自 | 4973 | 1850 | 1653 | +| chapter .mjs | 7721 | 2126 | 1904 | + +阈值是初始审查规则,不是测得的收益承诺或单次自动发布裁决: + +- 同环境中位数增加超过 max(25%, 绝对容差) 才产生计时 review signal;constructor/destroy 容差 2ms,ready 50ms,play Promise 10ms。绝对容差防止毫秒级噪声因比例被夸大;ready 容差还考虑 RAF/媒体噪声。发布前 ENG-08/MOD-03 结合更多配对样本复核阈值。 +- 同一分发文件、相同压缩方法增加超过 max(5%, 1024 bytes) 必须解释。不同格式、总安装体积、不同来源不可混比;较小变化不豁免接口或依赖审查。 +- 新增可复现的销毁后监听响应、RAF、DOM/实例持续增长或未说明残留资源属于功能/生命周期阻断项,不能用计时改善抵消。BASE-PERF-01 作为已有问题有明确修复责任。 + +## 命令和维护入口 + +1. 运行 `node refactor/scripts/browser-server.mjs`,打开 `http://127.0.0.1:8083/fixtures/performance.html` 并点击 Run performance baseline。保持前台,采样期间不要同时构建/压缩或运行其他重负载。 +2. 显示 Saved 12 timing samples and 6 resource probes / errors 0 后,运行 `node refactor/scripts/performance.mjs --compare refactor/.cache/reports/performance.json`。比较会验证来源、媒体、前台状态及基本清理,再输出中位数、计时审查信号和资源 profile 差异;时间信号要求配对复测。 +3. 重载重复,保留每轮报告,不覆盖历史证据。`performance.mjs --check` 只校验已存报告,不重跑浏览器。`sizes.mjs --check` 会重算真实发布文件压缩大小,工作区部分仍为历史清单。 +4. `node --test refactor/scripts/performance.test.mjs` / `yarn test:baseline` 包含假播放、后台、缺样本、清理失败、设备不一致、重大变慢和体积遗漏负例。计时比较排除预热,并允许候选修正历史残留后报告明确差异。 + +performance.js 负责实际采样与有限资源追踪,performance.mjs 负责数据有效性、统计和比较,sizes.mjs 负责内容哈希与压缩。任务归属:BASE-06 提供首批基线;ENG-08 参数化候选与趋势/体积准入;MOD-03 核心性能、MOD-04 重型插件/proxy、CORE-17/04/18 处理已复现残留。未覆盖的字幕/worker/模型/网络/GPU/真机长期资源验证仍由对应包和发布复盘承担。 diff --git a/refactor/baselines/performance.json b/refactor/baselines/performance.json new file mode 100644 index 000000000..56056defc --- /dev/null +++ b/refactor/baselines/performance.json @@ -0,0 +1,1488 @@ +{ + "schemaVersion": 1, + "task": "BASE-06", + "sourceCommit": "c7a375e1", + "browserSurface": "Codex in-app browser", + "timingThresholds": { + "constructorMs": { + "relative": 0.25, + "absoluteMs": 2 + }, + "readyMs": { + "relative": 0.25, + "absoluteMs": 50 + }, + "playResolvedMs": { + "relative": 0.25, + "absoluteMs": 10 + }, + "destroyMs": { + "relative": 0.25, + "absoluteMs": 2 + } + }, + "runs": [ + { + "kind": "performance", + "environment": { + "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/152.0.0.0 Safari/537.36", + "language": "zh-CN", + "hardwareConcurrency": 12, + "deviceMemory": 32, + "devicePixelRatio": 1, + "viewport": { + "width": 890, + "height": 1272 + }, + "visibility": "visible" + }, + "scripts": [ + "/releases/artplayer/dist/artplayer.js", + "/releases/artplayer-plugin-chapter/dist/artplayer-plugin-chapter.js", + "/fixtures/performance.js" + ], + "samples": [ + { + "configuration": "core", + "warmup": true, + "round": 0, + "constructorMs": 8.099999994039536, + "readyMs": 27.700000002980232, + "playResolvedMs": 5, + "playbackObservedMs": 234.5, + "mediaProgress": 0.16374, + "videoWidth": 640, + "nodes": 113, + "proxyCleanupEntries": 57, + "destroyMs": 3.5999999940395355, + "afterDestroy": { + "nodes": 0, + "instances": 0, + "proxyCleanupEntries": 0, + "paused": true, + "sourceAttribute": null + } + }, + { + "configuration": "chapter", + "warmup": true, + "round": 0, + "constructorMs": 7.5999999940395355, + "readyMs": 28.799999997019768, + "playResolvedMs": 2.0999999940395355, + "playbackObservedMs": 233.09999999403954, + "mediaProgress": 0.164939, + "videoWidth": 640, + "nodes": 125, + "proxyCleanupEntries": 57, + "destroyMs": 1.5, + "afterDestroy": { + "nodes": 0, + "instances": 0, + "proxyCleanupEntries": 0, + "paused": true, + "sourceAttribute": null + } + }, + { + "configuration": "core", + "warmup": false, + "round": 1, + "constructorMs": 3, + "readyMs": 15.800000011920929, + "playResolvedMs": 3.2999999970197678, + "playbackObservedMs": 233, + "mediaProgress": 0.16683, + "videoWidth": 640, + "nodes": 113, + "proxyCleanupEntries": 57, + "destroyMs": 2.800000011920929, + "afterDestroy": { + "nodes": 0, + "instances": 0, + "proxyCleanupEntries": 0, + "paused": true, + "sourceAttribute": null + } + }, + { + "configuration": "chapter", + "warmup": false, + "round": 1, + "constructorMs": 6.9000000059604645, + "readyMs": 30.700000002980232, + "playResolvedMs": 3.5999999940395355, + "playbackObservedMs": 233.29999999701977, + "mediaProgress": 0.161376, + "videoWidth": 640, + "nodes": 125, + "proxyCleanupEntries": 57, + "destroyMs": 3.4000000059604645, + "afterDestroy": { + "nodes": 0, + "instances": 0, + "proxyCleanupEntries": 0, + "paused": true, + "sourceAttribute": null + } + }, + { + "configuration": "core", + "warmup": false, + "round": 2, + "constructorMs": 5, + "readyMs": 12.400000005960464, + "playResolvedMs": 2.5, + "playbackObservedMs": 217.5, + "mediaProgress": 0.158314, + "videoWidth": 640, + "nodes": 113, + "proxyCleanupEntries": 57, + "destroyMs": 5.799999997019768, + "afterDestroy": { + "nodes": 0, + "instances": 0, + "proxyCleanupEntries": 0, + "paused": true, + "sourceAttribute": null + } + }, + { + "configuration": "chapter", + "warmup": false, + "round": 2, + "constructorMs": 3.8999999910593033, + "readyMs": 27, + "playResolvedMs": 4.399999991059303, + "playbackObservedMs": 232.29999999701977, + "mediaProgress": 0.161005, + "videoWidth": 640, + "nodes": 125, + "proxyCleanupEntries": 57, + "destroyMs": 3.1000000089406967, + "afterDestroy": { + "nodes": 0, + "instances": 0, + "proxyCleanupEntries": 0, + "paused": true, + "sourceAttribute": null + } + }, + { + "configuration": "core", + "warmup": false, + "round": 3, + "constructorMs": 5.600000008940697, + "readyMs": 31.200000002980232, + "playResolvedMs": 4.0999999940395355, + "playbackObservedMs": 215.79999999701977, + "mediaProgress": 0.151102, + "videoWidth": 640, + "nodes": 113, + "proxyCleanupEntries": 57, + "destroyMs": 3, + "afterDestroy": { + "nodes": 0, + "instances": 0, + "proxyCleanupEntries": 0, + "paused": true, + "sourceAttribute": null + } + }, + { + "configuration": "chapter", + "warmup": false, + "round": 3, + "constructorMs": 4.700000002980232, + "readyMs": 14.700000002980232, + "playResolvedMs": 1.9000000059604645, + "playbackObservedMs": 215.40000000596046, + "mediaProgress": 0.15072, + "videoWidth": 640, + "nodes": 125, + "proxyCleanupEntries": 57, + "destroyMs": 3, + "afterDestroy": { + "nodes": 0, + "instances": 0, + "proxyCleanupEntries": 0, + "paused": true, + "sourceAttribute": null + } + }, + { + "configuration": "core", + "warmup": false, + "round": 4, + "constructorMs": 7, + "readyMs": 30.19999998807907, + "playResolvedMs": 3, + "playbackObservedMs": 233.30000001192093, + "mediaProgress": 0.161219, + "videoWidth": 640, + "nodes": 113, + "proxyCleanupEntries": 57, + "destroyMs": 3, + "afterDestroy": { + "nodes": 0, + "instances": 0, + "proxyCleanupEntries": 0, + "paused": true, + "sourceAttribute": null + } + }, + { + "configuration": "chapter", + "warmup": false, + "round": 4, + "constructorMs": 7.5, + "readyMs": 29.799999997019768, + "playResolvedMs": 3.4000000059604645, + "playbackObservedMs": 233.70000000298023, + "mediaProgress": 0.170126, + "videoWidth": 640, + "nodes": 125, + "proxyCleanupEntries": 57, + "destroyMs": 3.1000000089406967, + "afterDestroy": { + "nodes": 0, + "instances": 0, + "proxyCleanupEntries": 0, + "paused": true, + "sourceAttribute": null + } + }, + { + "configuration": "core", + "warmup": false, + "round": 5, + "constructorMs": 6.200000002980232, + "readyMs": 31.099999994039536, + "playResolvedMs": 3, + "playbackObservedMs": 232.5, + "mediaProgress": 0.151235, + "videoWidth": 640, + "nodes": 113, + "proxyCleanupEntries": 57, + "destroyMs": 3.199999988079071, + "afterDestroy": { + "nodes": 0, + "instances": 0, + "proxyCleanupEntries": 0, + "paused": true, + "sourceAttribute": null + } + }, + { + "configuration": "chapter", + "warmup": false, + "round": 5, + "constructorMs": 5.700000002980232, + "readyMs": 30.099999994039536, + "playResolvedMs": 2.9000000059604645, + "playbackObservedMs": 232.90000000596046, + "mediaProgress": 0.161492, + "videoWidth": 640, + "nodes": 125, + "proxyCleanupEntries": 57, + "destroyMs": 3.7000000029802322, + "afterDestroy": { + "nodes": 0, + "instances": 0, + "proxyCleanupEntries": 0, + "paused": true, + "sourceAttribute": null + } + } + ], + "resources": [ + { + "configuration": "core", + "round": 0, + "useRaf": true, + "before": { + "timers": [ + { + "kind": "timeout", + "delay": 1000 + }, + { + "kind": "raf", + "delay": null + }, + { + "kind": "timeout", + "delay": 2000 + }, + { + "kind": "timeout", + "delay": 200 + } + ], + "proxyCleanupEntries": 58, + "frames": 2, + "proxyCalls": 1 + }, + "immediatelyAfter": [ + { + "kind": "timeout", + "delay": 200 + } + ], + "after": { + "observedMs": 364.30000001192093, + "timers": [ + { + "kind": "timeout", + "delay": 2000 + } + ], + "lateCallbacks": [ + { + "kind": "timeout", + "delay": 200 + } + ], + "lateResizeEvents": 1, + "framesAfterDestroy": 0, + "proxyCalls": 1, + "proxyCleanupEntries": 0, + "nodes": 0, + "instances": 0 + } + }, + { + "configuration": "chapter", + "round": 0, + "useRaf": true, + "before": { + "timers": [ + { + "kind": "timeout", + "delay": 1000 + }, + { + "kind": "raf", + "delay": null + }, + { + "kind": "timeout", + "delay": 2000 + }, + { + "kind": "timeout", + "delay": 200 + } + ], + "proxyCleanupEntries": 58, + "frames": 2, + "proxyCalls": 1 + }, + "immediatelyAfter": [ + { + "kind": "timeout", + "delay": 200 + } + ], + "after": { + "observedMs": 354.3999999910593, + "timers": [ + { + "kind": "timeout", + "delay": 2000 + } + ], + "lateCallbacks": [ + { + "kind": "timeout", + "delay": 200 + } + ], + "lateResizeEvents": 1, + "framesAfterDestroy": 0, + "proxyCalls": 1, + "proxyCleanupEntries": 0, + "nodes": 0, + "instances": 0 + } + }, + { + "configuration": "core", + "round": 1, + "useRaf": true, + "before": { + "timers": [ + { + "kind": "timeout", + "delay": 1000 + }, + { + "kind": "raf", + "delay": null + }, + { + "kind": "timeout", + "delay": 2000 + }, + { + "kind": "timeout", + "delay": 200 + } + ], + "proxyCleanupEntries": 58, + "frames": 2, + "proxyCalls": 1 + }, + "immediatelyAfter": [ + { + "kind": "timeout", + "delay": 200 + } + ], + "after": { + "observedMs": 361.1000000089407, + "timers": [ + { + "kind": "timeout", + "delay": 2000 + } + ], + "lateCallbacks": [ + { + "kind": "timeout", + "delay": 200 + } + ], + "lateResizeEvents": 1, + "framesAfterDestroy": 0, + "proxyCalls": 1, + "proxyCleanupEntries": 0, + "nodes": 0, + "instances": 0 + } + }, + { + "configuration": "chapter", + "round": 1, + "useRaf": true, + "before": { + "timers": [ + { + "kind": "timeout", + "delay": 1000 + }, + { + "kind": "raf", + "delay": null + }, + { + "kind": "timeout", + "delay": 2000 + }, + { + "kind": "timeout", + "delay": 200 + } + ], + "proxyCleanupEntries": 58, + "frames": 2, + "proxyCalls": 1 + }, + "immediatelyAfter": [ + { + "kind": "timeout", + "delay": 200 + } + ], + "after": { + "observedMs": 358.8999999910593, + "timers": [ + { + "kind": "timeout", + "delay": 2000 + } + ], + "lateCallbacks": [ + { + "kind": "timeout", + "delay": 200 + } + ], + "lateResizeEvents": 1, + "framesAfterDestroy": 0, + "proxyCalls": 1, + "proxyCleanupEntries": 0, + "nodes": 0, + "instances": 0 + } + }, + { + "configuration": "core", + "round": 2, + "useRaf": true, + "before": { + "timers": [ + { + "kind": "timeout", + "delay": 1000 + }, + { + "kind": "raf", + "delay": null + }, + { + "kind": "timeout", + "delay": 2000 + }, + { + "kind": "timeout", + "delay": 200 + } + ], + "proxyCleanupEntries": 58, + "frames": 2, + "proxyCalls": 1 + }, + "immediatelyAfter": [ + { + "kind": "timeout", + "delay": 200 + } + ], + "after": { + "observedMs": 364.59999999403954, + "timers": [ + { + "kind": "timeout", + "delay": 2000 + } + ], + "lateCallbacks": [ + { + "kind": "timeout", + "delay": 200 + } + ], + "lateResizeEvents": 1, + "framesAfterDestroy": 0, + "proxyCalls": 1, + "proxyCleanupEntries": 0, + "nodes": 0, + "instances": 0 + } + }, + { + "configuration": "chapter", + "round": 2, + "useRaf": true, + "before": { + "timers": [ + { + "kind": "timeout", + "delay": 1000 + }, + { + "kind": "raf", + "delay": null + }, + { + "kind": "timeout", + "delay": 2000 + }, + { + "kind": "timeout", + "delay": 200 + } + ], + "proxyCleanupEntries": 58, + "frames": 2, + "proxyCalls": 1 + }, + "immediatelyAfter": [ + { + "kind": "timeout", + "delay": 200 + } + ], + "after": { + "observedMs": 350.20000000298023, + "timers": [ + { + "kind": "timeout", + "delay": 2000 + } + ], + "lateCallbacks": [ + { + "kind": "timeout", + "delay": 200 + } + ], + "lateResizeEvents": 1, + "framesAfterDestroy": 0, + "proxyCalls": 1, + "proxyCleanupEntries": 0, + "nodes": 0, + "instances": 0 + } + } + ], + "errors": [], + "unhandled": [], + "visibilityChanges": [], + "remainingInstances": 0, + "capture": { + "capturedAt": "2026-09-10T12:39:24.007Z", + "releases": [ + { + "name": "artplayer", + "version": "5.4.0", + "integrity": "sha512-2B+plbx8N2yNsjK4nJU3+EOG8TULm1LRZk/QPkWRAMEX2Ee/MSnZG/WJYz8kcoZxZuLKcQ3uXifqLuPxZOH29A==", + "member": "package/dist/artplayer.js", + "sha256": "f1db1fa3406aa6d41baa7c554749429a8e79f99d56a794bde23345eb9c07573f" + }, + { + "name": "artplayer-plugin-chapter", + "version": "1.1.0", + "integrity": "sha512-ji66Lr2K2S+OjFMuMby3yq+pefWlOC51Sbpop/DIr2N6w3F0smrF+YZbshN1Dy8/Tx1TYpT7N6WkkZWy5Jix1w==", + "member": "package/dist/artplayer-plugin-chapter.js", + "sha256": "c2aaee11bf1db765433b01d9f8dd3978e41fa4d39655db00ebd03fc0be3e35e0" + } + ], + "fixtureHashAlgorithm": "sha256-lf", + "fixtures": { + "performance.html": "0a039781773f0c90edf6cb9fbe11049d321ee971dae8ae0b8779707648775508", + "performance.js": "f72abbead56dc6499c5f08cebbd90fffc9fa9ca42d788f71ddcce31f70259a0f" + }, + "media": { + "video.mp4": "30a2de667ba267b6bc605edcee1c4bd728c048ed76f500ea0e73d1f1a6f8f980" + } + } + }, + { + "kind": "performance", + "environment": { + "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/152.0.0.0 Safari/537.36", + "language": "zh-CN", + "hardwareConcurrency": 12, + "deviceMemory": 32, + "devicePixelRatio": 1, + "viewport": { + "width": 890, + "height": 1272 + }, + "visibility": "visible" + }, + "scripts": [ + "/releases/artplayer/dist/artplayer.js", + "/releases/artplayer-plugin-chapter/dist/artplayer-plugin-chapter.js", + "/fixtures/performance.js" + ], + "samples": [ + { + "configuration": "core", + "warmup": true, + "round": 0, + "constructorMs": 10, + "readyMs": 42.8999999910593, + "playResolvedMs": 5.100000008940697, + "playbackObservedMs": 232.79999999701977, + "mediaProgress": 0.160365, + "videoWidth": 640, + "nodes": 113, + "proxyCleanupEntries": 57, + "destroyMs": 1.2000000029802322, + "afterDestroy": { + "nodes": 0, + "instances": 0, + "proxyCleanupEntries": 0, + "paused": true, + "sourceAttribute": null + } + }, + { + "configuration": "chapter", + "warmup": true, + "round": 0, + "constructorMs": 2.9000000059604645, + "readyMs": 15.900000005960464, + "playResolvedMs": 1.2999999970197678, + "playbackObservedMs": 216.79999999701977, + "mediaProgress": 0.1609, + "videoWidth": 640, + "nodes": 125, + "proxyCleanupEntries": 57, + "destroyMs": 3, + "afterDestroy": { + "nodes": 0, + "instances": 0, + "proxyCleanupEntries": 0, + "paused": true, + "sourceAttribute": null + } + }, + { + "configuration": "core", + "warmup": false, + "round": 1, + "constructorMs": 4.0999999940395355, + "readyMs": 12.799999997019768, + "playResolvedMs": 3.1000000089406967, + "playbackObservedMs": 216.6000000089407, + "mediaProgress": 0.1511, + "videoWidth": 640, + "nodes": 113, + "proxyCleanupEntries": 57, + "destroyMs": 1.7999999970197678, + "afterDestroy": { + "nodes": 0, + "instances": 0, + "proxyCleanupEntries": 0, + "paused": true, + "sourceAttribute": null + } + }, + { + "configuration": "chapter", + "warmup": false, + "round": 1, + "constructorMs": 3.1000000089406967, + "readyMs": 14.5, + "playResolvedMs": 1.9000000059604645, + "playbackObservedMs": 217.40000000596046, + "mediaProgress": 0.157789, + "videoWidth": 640, + "nodes": 125, + "proxyCleanupEntries": 57, + "destroyMs": 3.2000000029802322, + "afterDestroy": { + "nodes": 0, + "instances": 0, + "proxyCleanupEntries": 0, + "paused": true, + "sourceAttribute": null + } + }, + { + "configuration": "core", + "warmup": false, + "round": 2, + "constructorMs": 3.6000000089406967, + "readyMs": 12.600000008940697, + "playResolvedMs": 1.5999999940395355, + "playbackObservedMs": 217, + "mediaProgress": 0.150429, + "videoWidth": 640, + "nodes": 113, + "proxyCleanupEntries": 57, + "destroyMs": 0.9000000059604645, + "afterDestroy": { + "nodes": 0, + "instances": 0, + "proxyCleanupEntries": 0, + "paused": true, + "sourceAttribute": null + } + }, + { + "configuration": "chapter", + "warmup": false, + "round": 2, + "constructorMs": 1.7000000029802322, + "readyMs": 15.700000002980232, + "playResolvedMs": 1.2999999970197678, + "playbackObservedMs": 217.5, + "mediaProgress": 0.161528, + "videoWidth": 640, + "nodes": 125, + "proxyCleanupEntries": 57, + "destroyMs": 4, + "afterDestroy": { + "nodes": 0, + "instances": 0, + "proxyCleanupEntries": 0, + "paused": true, + "sourceAttribute": null + } + }, + { + "configuration": "core", + "warmup": false, + "round": 3, + "constructorMs": 3.6000000089406967, + "readyMs": 12, + "playResolvedMs": 2.5, + "playbackObservedMs": 217.29999999701977, + "mediaProgress": 0.153246, + "videoWidth": 640, + "nodes": 113, + "proxyCleanupEntries": 57, + "destroyMs": 2.7999999970197678, + "afterDestroy": { + "nodes": 0, + "instances": 0, + "proxyCleanupEntries": 0, + "paused": true, + "sourceAttribute": null + } + }, + { + "configuration": "chapter", + "warmup": false, + "round": 3, + "constructorMs": 5.600000008940697, + "readyMs": 39.5, + "playResolvedMs": 1.2000000029802322, + "playbackObservedMs": 207.70000000298023, + "mediaProgress": 0.160302, + "videoWidth": 640, + "nodes": 125, + "proxyCleanupEntries": 57, + "destroyMs": 2.5, + "afterDestroy": { + "nodes": 0, + "instances": 0, + "proxyCleanupEntries": 0, + "paused": true, + "sourceAttribute": null + } + }, + { + "configuration": "core", + "warmup": false, + "round": 4, + "constructorMs": 4.5999999940395355, + "readyMs": 14.400000005960464, + "playResolvedMs": 3.3999999910593033, + "playbackObservedMs": 232.69999998807907, + "mediaProgress": 0.164161, + "videoWidth": 640, + "nodes": 113, + "proxyCleanupEntries": 57, + "destroyMs": 3.3999999910593033, + "afterDestroy": { + "nodes": 0, + "instances": 0, + "proxyCleanupEntries": 0, + "paused": true, + "sourceAttribute": null + } + }, + { + "configuration": "chapter", + "warmup": false, + "round": 4, + "constructorMs": 5, + "readyMs": 12.400000005960464, + "playResolvedMs": 2.5, + "playbackObservedMs": 217.5, + "mediaProgress": 0.158221, + "videoWidth": 640, + "nodes": 125, + "proxyCleanupEntries": 57, + "destroyMs": 2.9000000059604645, + "afterDestroy": { + "nodes": 0, + "instances": 0, + "proxyCleanupEntries": 0, + "paused": true, + "sourceAttribute": null + } + }, + { + "configuration": "core", + "warmup": false, + "round": 5, + "constructorMs": 5.5, + "readyMs": 30.30000001192093, + "playResolvedMs": 4.199999988079071, + "playbackObservedMs": 233, + "mediaProgress": 0.161452, + "videoWidth": 640, + "nodes": 113, + "proxyCleanupEntries": 57, + "destroyMs": 3.1000000089406967, + "afterDestroy": { + "nodes": 0, + "instances": 0, + "proxyCleanupEntries": 0, + "paused": true, + "sourceAttribute": null + } + }, + { + "configuration": "chapter", + "warmup": false, + "round": 5, + "constructorMs": 5.799999997019768, + "readyMs": 12.099999994039536, + "playResolvedMs": 1.4000000059604645, + "playbackObservedMs": 234.30000001192093, + "mediaProgress": 0.164744, + "videoWidth": 640, + "nodes": 125, + "proxyCleanupEntries": 57, + "destroyMs": 3.9000000059604645, + "afterDestroy": { + "nodes": 0, + "instances": 0, + "proxyCleanupEntries": 0, + "paused": true, + "sourceAttribute": null + } + } + ], + "resources": [ + { + "configuration": "core", + "round": 0, + "useRaf": true, + "before": { + "timers": [ + { + "kind": "timeout", + "delay": 1000 + }, + { + "kind": "raf", + "delay": null + }, + { + "kind": "timeout", + "delay": 2000 + }, + { + "kind": "timeout", + "delay": 200 + } + ], + "proxyCleanupEntries": 58, + "frames": 2, + "proxyCalls": 1 + }, + "immediatelyAfter": [ + { + "kind": "timeout", + "delay": 200 + } + ], + "after": { + "observedMs": 364.29999999701977, + "timers": [ + { + "kind": "timeout", + "delay": 2000 + } + ], + "lateCallbacks": [ + { + "kind": "timeout", + "delay": 200 + } + ], + "lateResizeEvents": 1, + "framesAfterDestroy": 0, + "proxyCalls": 1, + "proxyCleanupEntries": 0, + "nodes": 0, + "instances": 0 + } + }, + { + "configuration": "chapter", + "round": 0, + "useRaf": true, + "before": { + "timers": [ + { + "kind": "timeout", + "delay": 1000 + }, + { + "kind": "raf", + "delay": null + }, + { + "kind": "timeout", + "delay": 2000 + }, + { + "kind": "timeout", + "delay": 200 + } + ], + "proxyCleanupEntries": 58, + "frames": 2, + "proxyCalls": 1 + }, + "immediatelyAfter": [ + { + "kind": "timeout", + "delay": 200 + } + ], + "after": { + "observedMs": 350.8999999910593, + "timers": [ + { + "kind": "timeout", + "delay": 2000 + } + ], + "lateCallbacks": [ + { + "kind": "timeout", + "delay": 200 + } + ], + "lateResizeEvents": 1, + "framesAfterDestroy": 0, + "proxyCalls": 1, + "proxyCleanupEntries": 0, + "nodes": 0, + "instances": 0 + } + }, + { + "configuration": "core", + "round": 1, + "useRaf": true, + "before": { + "timers": [ + { + "kind": "timeout", + "delay": 1000 + }, + { + "kind": "raf", + "delay": null + }, + { + "kind": "timeout", + "delay": 2000 + }, + { + "kind": "timeout", + "delay": 200 + } + ], + "proxyCleanupEntries": 58, + "frames": 2, + "proxyCalls": 1 + }, + "immediatelyAfter": [ + { + "kind": "timeout", + "delay": 200 + } + ], + "after": { + "observedMs": 356.59999999403954, + "timers": [ + { + "kind": "timeout", + "delay": 2000 + } + ], + "lateCallbacks": [ + { + "kind": "timeout", + "delay": 200 + } + ], + "lateResizeEvents": 1, + "framesAfterDestroy": 0, + "proxyCalls": 1, + "proxyCleanupEntries": 0, + "nodes": 0, + "instances": 0 + } + }, + { + "configuration": "chapter", + "round": 1, + "useRaf": true, + "before": { + "timers": [ + { + "kind": "timeout", + "delay": 1000 + }, + { + "kind": "raf", + "delay": null + }, + { + "kind": "timeout", + "delay": 2000 + }, + { + "kind": "timeout", + "delay": 200 + } + ], + "proxyCleanupEntries": 58, + "frames": 2, + "proxyCalls": 1 + }, + "immediatelyAfter": [ + { + "kind": "timeout", + "delay": 200 + } + ], + "after": { + "observedMs": 357.5, + "timers": [ + { + "kind": "timeout", + "delay": 2000 + } + ], + "lateCallbacks": [ + { + "kind": "timeout", + "delay": 200 + } + ], + "lateResizeEvents": 1, + "framesAfterDestroy": 0, + "proxyCalls": 1, + "proxyCleanupEntries": 0, + "nodes": 0, + "instances": 0 + } + }, + { + "configuration": "core", + "round": 2, + "useRaf": true, + "before": { + "timers": [ + { + "kind": "timeout", + "delay": 1000 + }, + { + "kind": "raf", + "delay": null + }, + { + "kind": "timeout", + "delay": 2000 + }, + { + "kind": "timeout", + "delay": 200 + } + ], + "proxyCleanupEntries": 58, + "frames": 2, + "proxyCalls": 1 + }, + "immediatelyAfter": [ + { + "kind": "timeout", + "delay": 200 + } + ], + "after": { + "observedMs": 362.8999999910593, + "timers": [ + { + "kind": "timeout", + "delay": 2000 + } + ], + "lateCallbacks": [ + { + "kind": "timeout", + "delay": 200 + } + ], + "lateResizeEvents": 1, + "framesAfterDestroy": 0, + "proxyCalls": 1, + "proxyCleanupEntries": 0, + "nodes": 0, + "instances": 0 + } + }, + { + "configuration": "chapter", + "round": 2, + "useRaf": true, + "before": { + "timers": [ + { + "kind": "timeout", + "delay": 1000 + }, + { + "kind": "raf", + "delay": null + }, + { + "kind": "timeout", + "delay": 2000 + }, + { + "kind": "timeout", + "delay": 200 + } + ], + "proxyCleanupEntries": 58, + "frames": 2, + "proxyCalls": 1 + }, + "immediatelyAfter": [ + { + "kind": "timeout", + "delay": 200 + } + ], + "after": { + "observedMs": 364.5, + "timers": [ + { + "kind": "timeout", + "delay": 2000 + } + ], + "lateCallbacks": [ + { + "kind": "timeout", + "delay": 200 + } + ], + "lateResizeEvents": 1, + "framesAfterDestroy": 0, + "proxyCalls": 1, + "proxyCleanupEntries": 0, + "nodes": 0, + "instances": 0 + } + } + ], + "errors": [], + "unhandled": [], + "visibilityChanges": [], + "remainingInstances": 0, + "capture": { + "capturedAt": "2026-09-10T12:42:22.321Z", + "releases": [ + { + "name": "artplayer", + "version": "5.4.0", + "integrity": "sha512-2B+plbx8N2yNsjK4nJU3+EOG8TULm1LRZk/QPkWRAMEX2Ee/MSnZG/WJYz8kcoZxZuLKcQ3uXifqLuPxZOH29A==", + "member": "package/dist/artplayer.js", + "sha256": "f1db1fa3406aa6d41baa7c554749429a8e79f99d56a794bde23345eb9c07573f" + }, + { + "name": "artplayer-plugin-chapter", + "version": "1.1.0", + "integrity": "sha512-ji66Lr2K2S+OjFMuMby3yq+pefWlOC51Sbpop/DIr2N6w3F0smrF+YZbshN1Dy8/Tx1TYpT7N6WkkZWy5Jix1w==", + "member": "package/dist/artplayer-plugin-chapter.js", + "sha256": "c2aaee11bf1db765433b01d9f8dd3978e41fa4d39655db00ebd03fc0be3e35e0" + } + ], + "fixtureHashAlgorithm": "sha256-lf", + "fixtures": { + "performance.html": "0a039781773f0c90edf6cb9fbe11049d321ee971dae8ae0b8779707648775508", + "performance.js": "f72abbead56dc6499c5f08cebbd90fffc9fa9ca42d788f71ddcce31f70259a0f" + }, + "media": { + "video.mp4": "30a2de667ba267b6bc605edcee1c4bd728c048ed76f500ea0e73d1f1a6f8f980" + } + } + } + ], + "summaries": [ + { + "core": { + "constructorMs": { + "count": 5, + "min": 3, + "median": 5.600000008940697, + "max": 7 + }, + "readyMs": { + "count": 5, + "min": 12.400000005960464, + "median": 30.19999998807907, + "max": 31.200000002980232 + }, + "playResolvedMs": { + "count": 5, + "min": 2.5, + "median": 3, + "max": 4.0999999940395355 + }, + "destroyMs": { + "count": 5, + "min": 2.800000011920929, + "median": 3, + "max": 5.799999997019768 + } + }, + "chapter": { + "constructorMs": { + "count": 5, + "min": 3.8999999910593033, + "median": 5.700000002980232, + "max": 7.5 + }, + "readyMs": { + "count": 5, + "min": 14.700000002980232, + "median": 29.799999997019768, + "max": 30.700000002980232 + }, + "playResolvedMs": { + "count": 5, + "min": 1.9000000059604645, + "median": 3.4000000059604645, + "max": 4.399999991059303 + }, + "destroyMs": { + "count": 5, + "min": 3, + "median": 3.1000000089406967, + "max": 3.7000000029802322 + } + } + }, + { + "core": { + "constructorMs": { + "count": 5, + "min": 3.6000000089406967, + "median": 4.0999999940395355, + "max": 5.5 + }, + "readyMs": { + "count": 5, + "min": 12, + "median": 12.799999997019768, + "max": 30.30000001192093 + }, + "playResolvedMs": { + "count": 5, + "min": 1.5999999940395355, + "median": 3.1000000089406967, + "max": 4.199999988079071 + }, + "destroyMs": { + "count": 5, + "min": 0.9000000059604645, + "median": 2.7999999970197678, + "max": 3.3999999910593033 + } + }, + "chapter": { + "constructorMs": { + "count": 5, + "min": 1.7000000029802322, + "median": 5, + "max": 5.799999997019768 + }, + "readyMs": { + "count": 5, + "min": 12.099999994039536, + "median": 14.5, + "max": 39.5 + }, + "playResolvedMs": { + "count": 5, + "min": 1.2000000029802322, + "median": 1.4000000059604645, + "max": 2.5 + }, + "destroyMs": { + "count": 5, + "min": 2.5, + "median": 3.2000000029802322, + "max": 4 + } + } + } + ], + "verification": { + "comparison": { + "summary": { + "core": { + "constructorMs": { + "count": 5, + "min": 3.6000000089406967, + "median": 4.0999999940395355, + "max": 5.5 + }, + "readyMs": { + "count": 5, + "min": 12, + "median": 12.799999997019768, + "max": 30.30000001192093 + }, + "playResolvedMs": { + "count": 5, + "min": 1.5999999940395355, + "median": 3.1000000089406967, + "max": 4.199999988079071 + }, + "destroyMs": { + "count": 5, + "min": 0.9000000059604645, + "median": 2.7999999970197678, + "max": 3.3999999910593033 + } + }, + "chapter": { + "constructorMs": { + "count": 5, + "min": 1.7000000029802322, + "median": 5, + "max": 5.799999997019768 + }, + "readyMs": { + "count": 5, + "min": 12.099999994039536, + "median": 14.5, + "max": 39.5 + }, + "playResolvedMs": { + "count": 5, + "min": 1.2000000029802322, + "median": 1.4000000059604645, + "max": 2.5 + }, + "destroyMs": { + "count": 5, + "min": 2.5, + "median": 3.2000000029802322, + "max": 4 + } + } + }, + "reviewSignals": [], + "resourceProfileChanged": false + } + }, + "findings": [ + { + "id": "BASE-PERF-01", + "owner": "CORE-17", + "relatedOwners": [ + "CORE-04", + "CORE-18" + ], + "observation": "Pending resize debounce runs after destroy and schedules a new notice timer; observed for at least 350ms, not proof of a permanent leak." + } + ], + "hostContext": { + "source": "Windows CIM read after measurement; not a browser benchmark API", + "cpu": "12th Gen Intel(R) Core(TM) i5-12400F", + "physicalCores": 6, + "logicalProcessors": 12, + "memoryGiB": 31.8 + } +} diff --git a/refactor/baselines/sizes.json b/refactor/baselines/sizes.json new file mode 100644 index 000000000..03c3772bd --- /dev/null +++ b/refactor/baselines/sizes.json @@ -0,0 +1,1036 @@ +{ + "schemaVersion": 1, + "task": "BASE-06", + "sourceCommit": "c7a375e1", + "capturedAt": "2026-09-10T12:43:04.099Z", + "node": "v24.21.0", + "zlib": "1.3.2.1-motley-8002e91", + "brotli": "1.2.0", + "note": "Independent file compression: gzip level 9, Brotli quality 6. Not production HTTP transfer size. Workspace files match BASE-05 observed hashes and may be stale; do not treat them as verified npm releases. Documentation site has no library bundle entry.", + "reviewThreshold": { + "relative": 0.05, + "absoluteBytes": 1024, + "rule": "Review if same-file increase exceeds max(5 percent, 1024 bytes); not an optimization or automatic release verdict" + }, + "published": [ + { + "name": "artplayer", + "version": "5.4.0", + "path": "package/dist/artplayer.js", + "sha256": "f1db1fa3406aa6d41baa7c554749429a8e79f99d56a794bde23345eb9c07573f", + "raw": 134037, + "gzip9": 35486, + "brotli6": 32533 + }, + { + "name": "artplayer", + "version": "5.4.0", + "path": "package/dist/artplayer.legacy.js", + "sha256": "cef83f9dac8a343060329ea6c5d603f0e7811fd0fd6c1590ae1c47f9e0afc9bb", + "raw": 135748, + "gzip9": 36021, + "brotli6": 33045 + }, + { + "name": "artplayer", + "version": "5.4.0", + "path": "package/dist/artplayer.mjs", + "sha256": "a1800b37ac7549f52fa960fe28bc6e1c69ec18bd4bc9a7e2534aecc3df10eb3e", + "raw": 208826, + "gzip9": 43868, + "brotli6": 40443 + }, + { + "name": "artplayer", + "version": "5.4.0", + "path": "package/dist/i18n/ar.js", + "sha256": "61c43469ee95a00dc624583f418653e3dcbf48b24ae6a4c203ad986234852365", + "raw": 1742, + "gzip9": 868, + "brotli6": 823 + }, + { + "name": "artplayer", + "version": "5.4.0", + "path": "package/dist/i18n/ar.mjs", + "sha256": "68922fdc9f80d3321ea0654c8ff8f5875b6715103d2b14ffcf17f93738b39cf9", + "raw": 1686, + "gzip9": 749, + "brotli6": 689 + }, + { + "name": "artplayer", + "version": "5.4.0", + "path": "package/dist/i18n/cs.js", + "sha256": "ad7bbf8853204a6955ef84bfbd932cab3f141a7e73a8145f28ba7a5b2b83b7c0", + "raw": 1441, + "gzip9": 797, + "brotli6": 770 + }, + { + "name": "artplayer", + "version": "5.4.0", + "path": "package/dist/i18n/cs.mjs", + "sha256": "29a489be767fda9d46b59c9adbaad323f17a5e67daf7f7aa78b7ce8fb5b4d63c", + "raw": 1385, + "gzip9": 688, + "brotli6": 680 + }, + { + "name": "artplayer", + "version": "5.4.0", + "path": "package/dist/i18n/es.js", + "sha256": "aaa95cc9645b734c58fba06fdbcdda962c4cb3a0e7eb6206f06d6168208cd86b", + "raw": 1398, + "gzip9": 733, + "brotli6": 703 + }, + { + "name": "artplayer", + "version": "5.4.0", + "path": "package/dist/i18n/es.mjs", + "sha256": "331d2ef74da2eec8f3304fec0b5340c795d9c1eec24e08167c9a7b66bf30973b", + "raw": 1342, + "gzip9": 630, + "brotli6": 613 + }, + { + "name": "artplayer", + "version": "5.4.0", + "path": "package/dist/i18n/fa.js", + "sha256": "c998467261cbdfd2c3fb16c0ae4b2c48c409f42f41aea35ed94766f1e12819d5", + "raw": 1597, + "gzip9": 855, + "brotli6": 812 + }, + { + "name": "artplayer", + "version": "5.4.0", + "path": "package/dist/i18n/fa.mjs", + "sha256": "b4c98894b46975cebf5ea9088bcf0b5bdfd408bc3c82f4e2e9128133c7de2d4d", + "raw": 1541, + "gzip9": 737, + "brotli6": 687 + }, + { + "name": "artplayer", + "version": "5.4.0", + "path": "package/dist/i18n/fr.js", + "sha256": "6b06e16b1fb01c8695fb5c10b32a00421399180de5dc5d845ce17010f2fd3e66", + "raw": 1413, + "gzip9": 733, + "brotli6": 709 + }, + { + "name": "artplayer", + "version": "5.4.0", + "path": "package/dist/i18n/fr.mjs", + "sha256": "abe8e3548fa7304f302e2c74818a6176edee8c3b65e33cb6f62e96d130749ee5", + "raw": 1357, + "gzip9": 634, + "brotli6": 624 + }, + { + "name": "artplayer", + "version": "5.4.0", + "path": "package/dist/i18n/id.js", + "sha256": "a5832c4bfc03c7f16418bf4b324d9773895541dc823ece9114741794737aad74", + "raw": 1347, + "gzip9": 703, + "brotli6": 679 + }, + { + "name": "artplayer", + "version": "5.4.0", + "path": "package/dist/i18n/id.mjs", + "sha256": "a40a433be6ca1ac1ee1810fe805ee60784d349e59b9ad82ea80201d660db4e68", + "raw": 1291, + "gzip9": 599, + "brotli6": 599 + }, + { + "name": "artplayer", + "version": "5.4.0", + "path": "package/dist/i18n/pl.js", + "sha256": "2491487062bdfc91d60f17c6e9a83ee196c991216d15f525fe3536b98873da2c", + "raw": 1402, + "gzip9": 791, + "brotli6": 765 + }, + { + "name": "artplayer", + "version": "5.4.0", + "path": "package/dist/i18n/pl.mjs", + "sha256": "ad8ea2c03785edbfe1f35761bec21b8a04213f9fa88a794d850bb3973564930f", + "raw": 1346, + "gzip9": 680, + "brotli6": 678 + }, + { + "name": "artplayer", + "version": "5.4.0", + "path": "package/dist/i18n/ru.js", + "sha256": "2d3a9ee6533cb6fa961f0a24a25ce63cc76992fca17e1769b6fa75104f8a1529", + "raw": 1998, + "gzip9": 995, + "brotli6": 938 + }, + { + "name": "artplayer", + "version": "5.4.0", + "path": "package/dist/i18n/ru.mjs", + "sha256": "a89b8c36cfd7c181c2b31aa823deda3d7c37b56b2b81746338c52ea1c1d93352", + "raw": 1942, + "gzip9": 881, + "brotli6": 808 + }, + { + "name": "artplayer", + "version": "5.4.0", + "path": "package/dist/i18n/tr.js", + "sha256": "438b06a4c3f479a2901b0085eaa7bdba8eaef87bdb07ff3faa559c85403fe433", + "raw": 1342, + "gzip9": 754, + "brotli6": 725 + }, + { + "name": "artplayer", + "version": "5.4.0", + "path": "package/dist/i18n/tr.mjs", + "sha256": "cc96f9cbb9c1587d5cd8f25b0b9800678ad76e93de089ae42c38dee16e6fe8fa", + "raw": 1286, + "gzip9": 646, + "brotli6": 638 + }, + { + "name": "artplayer", + "version": "5.4.0", + "path": "package/dist/i18n/vi.js", + "sha256": "1ffbd62843a902ea2967eab46432d3fc548f5633e53eed104314b523cacc46a8", + "raw": 1489, + "gzip9": 824, + "brotli6": 787 + }, + { + "name": "artplayer", + "version": "5.4.0", + "path": "package/dist/i18n/vi.mjs", + "sha256": "7872ded84622bcda20e8c1d70c597c2ba071b50701900efa47cc4683ee17f1a2", + "raw": 1433, + "gzip9": 712, + "brotli6": 696 + }, + { + "name": "artplayer", + "version": "5.4.0", + "path": "package/dist/i18n/zh-tw.js", + "sha256": "2d43577f98456488196921e1ec721695a95e1b8c827077286b02ce3fb987e8ff", + "raw": 1255, + "gzip9": 820, + "brotli6": 751 + }, + { + "name": "artplayer", + "version": "5.4.0", + "path": "package/dist/i18n/zh-tw.mjs", + "sha256": "7ec638b4babe59d3ab1d3e64abdd74a96fefb260a50e2cd7240f8d50a1340925", + "raw": 1197, + "gzip9": 695, + "brotli6": 620 + }, + { + "name": "artplayer-plugin-chapter", + "version": "1.1.0", + "path": "package/dist/artplayer-plugin-chapter.js", + "sha256": "c2aaee11bf1db765433b01d9f8dd3978e41fa4d39655db00ebd03fc0be3e35e0", + "raw": 4973, + "gzip9": 1850, + "brotli6": 1653 + }, + { + "name": "artplayer-plugin-chapter", + "version": "1.1.0", + "path": "package/dist/artplayer-plugin-chapter.legacy.js", + "sha256": "c2aaee11bf1db765433b01d9f8dd3978e41fa4d39655db00ebd03fc0be3e35e0", + "raw": 4973, + "gzip9": 1850, + "brotli6": 1653 + }, + { + "name": "artplayer-plugin-chapter", + "version": "1.1.0", + "path": "package/dist/artplayer-plugin-chapter.mjs", + "sha256": "61342a069b84e0731d44a2464d0dfe637d1514d0037c740371fc866c516d2209", + "raw": 7721, + "gzip9": 2126, + "brotli6": 1904 + } + ], + "workspaceObserved": [ + { + "name": "artplayer", + "version": "5.4.1", + "path": "dist/artplayer.js", + "sha256": "2ae05beeca573455af87b63259758f151f3c69e2a5553d6996cf1fcb161396b7", + "raw": 134753, + "gzip9": 35735, + "brotli6": 32757 + }, + { + "name": "artplayer", + "version": "5.4.1", + "path": "dist/artplayer.legacy.js", + "sha256": "3b85d82e59f0aaa61816ab66eb1a21735144a56310171b2ce571a00f2fb6f443", + "raw": 136473, + "gzip9": 36265, + "brotli6": 33246 + }, + { + "name": "artplayer", + "version": "5.4.1", + "path": "dist/artplayer.mjs", + "sha256": "f7df4dd5907dc58aaee1e456d7838e2ecfa352a74e219c08c318e80d98f94a0f", + "raw": 215072, + "gzip9": 44382, + "brotli6": 40944 + }, + { + "name": "artplayer", + "version": "5.4.1", + "path": "dist/i18n/ar.js", + "sha256": "61c43469ee95a00dc624583f418653e3dcbf48b24ae6a4c203ad986234852365", + "raw": 1742, + "gzip9": 868, + "brotli6": 823 + }, + { + "name": "artplayer", + "version": "5.4.1", + "path": "dist/i18n/ar.mjs", + "sha256": "fe7bf234e28e7c4405055051d230527ea5deb268168fe68bdc253cffd1af2703", + "raw": 1728, + "gzip9": 755, + "brotli6": 690 + }, + { + "name": "artplayer", + "version": "5.4.1", + "path": "dist/i18n/cs.js", + "sha256": "ad7bbf8853204a6955ef84bfbd932cab3f141a7e73a8145f28ba7a5b2b83b7c0", + "raw": 1441, + "gzip9": 797, + "brotli6": 770 + }, + { + "name": "artplayer", + "version": "5.4.1", + "path": "dist/i18n/cs.mjs", + "sha256": "a475449e19cffb67eb5762787752027bdc674f0d0d55fb10fbb5cd693dabe9da", + "raw": 1427, + "gzip9": 696, + "brotli6": 681 + }, + { + "name": "artplayer", + "version": "5.4.1", + "path": "dist/i18n/es.js", + "sha256": "aaa95cc9645b734c58fba06fdbcdda962c4cb3a0e7eb6206f06d6168208cd86b", + "raw": 1398, + "gzip9": 733, + "brotli6": 703 + }, + { + "name": "artplayer", + "version": "5.4.1", + "path": "dist/i18n/es.mjs", + "sha256": "f36b65a70247c580b9560ed5205a69916bf5d2b5c8bbbcaa41a4d015a0016272", + "raw": 1384, + "gzip9": 637, + "brotli6": 622 + }, + { + "name": "artplayer", + "version": "5.4.1", + "path": "dist/i18n/fa.js", + "sha256": "c998467261cbdfd2c3fb16c0ae4b2c48c409f42f41aea35ed94766f1e12819d5", + "raw": 1597, + "gzip9": 855, + "brotli6": 812 + }, + { + "name": "artplayer", + "version": "5.4.1", + "path": "dist/i18n/fa.mjs", + "sha256": "f44d249236e753606decc8b800f5f32888c6002d81975e1b1674f9a4c395cb8f", + "raw": 1583, + "gzip9": 745, + "brotli6": 690 + }, + { + "name": "artplayer", + "version": "5.4.1", + "path": "dist/i18n/fr.js", + "sha256": "6b06e16b1fb01c8695fb5c10b32a00421399180de5dc5d845ce17010f2fd3e66", + "raw": 1413, + "gzip9": 733, + "brotli6": 709 + }, + { + "name": "artplayer", + "version": "5.4.1", + "path": "dist/i18n/fr.mjs", + "sha256": "5b532775e7704e41f5ea5500d1d31d758f77b87c0d3e2e014f61ac3227cb3544", + "raw": 1399, + "gzip9": 642, + "brotli6": 634 + }, + { + "name": "artplayer", + "version": "5.4.1", + "path": "dist/i18n/id.js", + "sha256": "a5832c4bfc03c7f16418bf4b324d9773895541dc823ece9114741794737aad74", + "raw": 1347, + "gzip9": 703, + "brotli6": 679 + }, + { + "name": "artplayer", + "version": "5.4.1", + "path": "dist/i18n/id.mjs", + "sha256": "b18f86de99db2c5e71949f5c4e8e39130025b6d86e3dc61541fffd55826053d4", + "raw": 1333, + "gzip9": 607, + "brotli6": 600 + }, + { + "name": "artplayer", + "version": "5.4.1", + "path": "dist/i18n/pl.js", + "sha256": "2491487062bdfc91d60f17c6e9a83ee196c991216d15f525fe3536b98873da2c", + "raw": 1402, + "gzip9": 791, + "brotli6": 765 + }, + { + "name": "artplayer", + "version": "5.4.1", + "path": "dist/i18n/pl.mjs", + "sha256": "ba8f39c97ff5a4e5d28d62b91020c3b1f4844321eaad97a38d16beef58040be3", + "raw": 1388, + "gzip9": 688, + "brotli6": 677 + }, + { + "name": "artplayer", + "version": "5.4.1", + "path": "dist/i18n/ru.js", + "sha256": "2d3a9ee6533cb6fa961f0a24a25ce63cc76992fca17e1769b6fa75104f8a1529", + "raw": 1998, + "gzip9": 995, + "brotli6": 938 + }, + { + "name": "artplayer", + "version": "5.4.1", + "path": "dist/i18n/ru.mjs", + "sha256": "2e9ffc111f7d85170984d4e8a3d26b47eb4045a524696cc154dec11bd1495d96", + "raw": 1984, + "gzip9": 889, + "brotli6": 810 + }, + { + "name": "artplayer", + "version": "5.4.1", + "path": "dist/i18n/tr.js", + "sha256": "438b06a4c3f479a2901b0085eaa7bdba8eaef87bdb07ff3faa559c85403fe433", + "raw": 1342, + "gzip9": 754, + "brotli6": 725 + }, + { + "name": "artplayer", + "version": "5.4.1", + "path": "dist/i18n/tr.mjs", + "sha256": "a5a527bb40608558c1fe515e2a5a3552e6198eafbd79a2d10305f89cc3e7743f", + "raw": 1328, + "gzip9": 653, + "brotli6": 641 + }, + { + "name": "artplayer", + "version": "5.4.1", + "path": "dist/i18n/vi.js", + "sha256": "1ffbd62843a902ea2967eab46432d3fc548f5633e53eed104314b523cacc46a8", + "raw": 1489, + "gzip9": 824, + "brotli6": 787 + }, + { + "name": "artplayer", + "version": "5.4.1", + "path": "dist/i18n/vi.mjs", + "sha256": "06ac85d56d5d689d3db40e106d23cf06f6bdd867235b928613b9eb31ac3a51f8", + "raw": 1475, + "gzip9": 720, + "brotli6": 703 + }, + { + "name": "artplayer", + "version": "5.4.1", + "path": "dist/i18n/zh-tw.js", + "sha256": "2d43577f98456488196921e1ec721695a95e1b8c827077286b02ce3fb987e8ff", + "raw": 1255, + "gzip9": 820, + "brotli6": 751 + }, + { + "name": "artplayer", + "version": "5.4.1", + "path": "dist/i18n/zh-tw.mjs", + "sha256": "f6acdb6b64566abfa972bb2149ea7968f2f8c44c6d1cbc8813151f20d72c41bf", + "raw": 1239, + "gzip9": 705, + "brotli6": 619 + }, + { + "name": "artplayer-plugin-ads", + "version": "2.1.0", + "path": "dist/artplayer-plugin-ads.js", + "sha256": "ceb2d8a23a6735c161b31a4a427d8a757679aaf8a5a106ef40a6f047061f1df8", + "raw": 5620, + "gzip9": 1930, + "brotli6": 1734 + }, + { + "name": "artplayer-plugin-ads", + "version": "2.1.0", + "path": "dist/artplayer-plugin-ads.legacy.js", + "sha256": "1e10c3a6b51de18e54cd02dd342ab4010fc466de6257659cf1d2e087642aa9a3", + "raw": 5951, + "gzip9": 2090, + "brotli6": 1889 + }, + { + "name": "artplayer-plugin-ads", + "version": "2.1.0", + "path": "dist/artplayer-plugin-ads.mjs", + "sha256": "5d53a55bd6fcc64a01abe460a6e9161240ee23bc8b4cf160c22c602de03f6356", + "raw": 9577, + "gzip9": 2330, + "brotli6": 2119 + }, + { + "name": "artplayer-plugin-ambilight", + "version": "1.1.0", + "path": "dist/artplayer-plugin-ambilight.js", + "sha256": "8f32290c65a13b0a3026dee0045fef4125a9c9ac788ecb1675aef05f79172693", + "raw": 1844, + "gzip9": 1039, + "brotli6": 936 + }, + { + "name": "artplayer-plugin-ambilight", + "version": "1.1.0", + "path": "dist/artplayer-plugin-ambilight.legacy.js", + "sha256": "8f32290c65a13b0a3026dee0045fef4125a9c9ac788ecb1675aef05f79172693", + "raw": 1844, + "gzip9": 1039, + "brotli6": 936 + }, + { + "name": "artplayer-plugin-ambilight", + "version": "1.1.0", + "path": "dist/artplayer-plugin-ambilight.mjs", + "sha256": "b9b56fdec4a39b5d9dd2f839ddefbe5e01d74823d5879b75bb776825ed1b8140", + "raw": 3433, + "gzip9": 1212, + "brotli6": 1098 + }, + { + "name": "artplayer-plugin-asr", + "version": "2.1.0", + "path": "dist/artplayer-plugin-asr.js", + "sha256": "7f975b131a9ea207f88a157aafec778bc4906230500db9b30f5bbfbf327b251d", + "raw": 5064, + "gzip9": 2218, + "brotli6": 2041 + }, + { + "name": "artplayer-plugin-asr", + "version": "2.1.0", + "path": "dist/artplayer-plugin-asr.legacy.js", + "sha256": "8b9f07ce97a8ce2e4f29e41e79257be530fd7a76558369d34c3d7497ea606c33", + "raw": 5468, + "gzip9": 2344, + "brotli6": 2173 + }, + { + "name": "artplayer-plugin-asr", + "version": "2.1.0", + "path": "dist/artplayer-plugin-asr.mjs", + "sha256": "bf222a738fc7a8946769ebaf37c89d05968ec0d74fe1e6e5ec653e560cbb6eb8", + "raw": 9309, + "gzip9": 2808, + "brotli6": 2636 + }, + { + "name": "artplayer-plugin-audio-track", + "version": "1.1.0", + "path": "dist/artplayer-plugin-audio-track.js", + "sha256": "473f39f1d750f0722cca7e857c12c3c978ebe3c3b2352e325f1248318e508683", + "raw": 1471, + "gzip9": 676, + "brotli6": 620 + }, + { + "name": "artplayer-plugin-audio-track", + "version": "1.1.0", + "path": "dist/artplayer-plugin-audio-track.legacy.js", + "sha256": "d8dc74bce76112d7430c98e3165605e32fde5d3c603be4b496eac58f574576cb", + "raw": 1497, + "gzip9": 694, + "brotli6": 639 + }, + { + "name": "artplayer-plugin-audio-track", + "version": "1.1.0", + "path": "dist/artplayer-plugin-audio-track.mjs", + "sha256": "df9e2215d283450ba799545f38d26ed582dd245efe5abc31641bf88eb8d6faeb", + "raw": 2330, + "gzip9": 730, + "brotli6": 663 + }, + { + "name": "artplayer-plugin-auto-thumbnail", + "version": "1.1.0", + "path": "dist/artplayer-plugin-auto-thumbnail.js", + "sha256": "ce1f1472bf02b836dd85b92eadf2f00786c02cde11a20ac2801136a0f675d12a", + "raw": 1299, + "gzip9": 734, + "brotli6": 661 + }, + { + "name": "artplayer-plugin-auto-thumbnail", + "version": "1.1.0", + "path": "dist/artplayer-plugin-auto-thumbnail.legacy.js", + "sha256": "3561e51e0a5f294b56641bf0884a24a4a9e326582d2e99416a04f9526c7d0cc0", + "raw": 1949, + "gzip9": 1023, + "brotli6": 946 + }, + { + "name": "artplayer-plugin-auto-thumbnail", + "version": "1.1.0", + "path": "dist/artplayer-plugin-auto-thumbnail.mjs", + "sha256": "c362a86f38b3515c5d53a368cd94602e4531e93c638ed325fc179ec8664607f9", + "raw": 1894, + "gzip9": 793, + "brotli6": 712 + }, + { + "name": "artplayer-plugin-chapter", + "version": "1.1.0", + "path": "dist/artplayer-plugin-chapter.js", + "sha256": "c2aaee11bf1db765433b01d9f8dd3978e41fa4d39655db00ebd03fc0be3e35e0", + "raw": 4973, + "gzip9": 1850, + "brotli6": 1653 + }, + { + "name": "artplayer-plugin-chapter", + "version": "1.1.0", + "path": "dist/artplayer-plugin-chapter.legacy.js", + "sha256": "c2aaee11bf1db765433b01d9f8dd3978e41fa4d39655db00ebd03fc0be3e35e0", + "raw": 4973, + "gzip9": 1850, + "brotli6": 1653 + }, + { + "name": "artplayer-plugin-chapter", + "version": "1.1.0", + "path": "dist/artplayer-plugin-chapter.mjs", + "sha256": "226c9ab5fbf7ea8bb3d96bd73a1cec6f86eb054f369aafb686333b65e85edc0f", + "raw": 7880, + "gzip9": 2137, + "brotli6": 1921 + }, + { + "name": "artplayer-plugin-chromecast", + "version": "1.1.0", + "path": "dist/artplayer-plugin-chromecast.js", + "sha256": "4959661fc7f22eee3d32363bb0392a486c44499ec4a9c608ccfea55de29aaac6", + "raw": 3934, + "gzip9": 1851, + "brotli6": 1708 + }, + { + "name": "artplayer-plugin-chromecast", + "version": "1.1.0", + "path": "dist/artplayer-plugin-chromecast.legacy.js", + "sha256": "e2ba7aebec099884bb806f3caf77f9ff739ff9f236aefdfd0a4e69a8295c9d01", + "raw": 4472, + "gzip9": 2029, + "brotli6": 1870 + }, + { + "name": "artplayer-plugin-chromecast", + "version": "1.1.0", + "path": "dist/artplayer-plugin-chromecast.mjs", + "sha256": "0c96dad4cee48c353d91d19852243d566345cc7977e1e19ccbd9deba73190b8b", + "raw": 6709, + "gzip9": 2126, + "brotli6": 1970 + }, + { + "name": "artplayer-plugin-danmuku", + "version": "5.3.0", + "path": "dist/artplayer-plugin-danmuku.js", + "sha256": "7c8749288711ef97e80b6f9f00981170aa73f62a8ae25d6d663749a4aef62a8f", + "raw": 52390, + "gzip9": 14529, + "brotli6": 13578 + }, + { + "name": "artplayer-plugin-danmuku", + "version": "5.3.0", + "path": "dist/artplayer-plugin-danmuku.legacy.js", + "sha256": "62db96685c48b8573f0480cead6ac934b1d0382b9fdd0046d17d15d2549c56dc", + "raw": 53263, + "gzip9": 14894, + "brotli6": 14001 + }, + { + "name": "artplayer-plugin-danmuku", + "version": "5.3.0", + "path": "dist/artplayer-plugin-danmuku.mjs", + "sha256": "f9e1c59adac3f399c022c5e5e6aef7c134e489862915141f25f931316e254f12", + "raw": 77263, + "gzip9": 18502, + "brotli6": 17068 + }, + { + "name": "artplayer-plugin-danmuku-mask", + "version": "1.1.0", + "path": "dist/artplayer-plugin-danmuku-mask.js", + "sha256": "07cebbfbf77f8ec4b2df6a77d7d7300345b86f2993e220ff14e1aae530e4fb31", + "raw": 904243, + "gzip9": 229221, + "brotli6": 201958 + }, + { + "name": "artplayer-plugin-danmuku-mask", + "version": "1.1.0", + "path": "dist/artplayer-plugin-danmuku-mask.legacy.js", + "sha256": "a678a3c0f6d3920bee3b66af9943b3612935028bff61c96677b8eaf8ef7cc8f0", + "raw": 907166, + "gzip9": 229714, + "brotli6": 202538 + }, + { + "name": "artplayer-plugin-danmuku-mask", + "version": "1.1.0", + "path": "dist/artplayer-plugin-danmuku-mask.mjs", + "sha256": "f07030990a8d6adbe6db0acdacbae9db6e6c33f0fb8126e09697184d0ef8396d", + "raw": 1777425, + "gzip9": 320210, + "brotli6": 277273 + }, + { + "name": "artplayer-plugin-dash-control", + "version": "1.1.0", + "path": "dist/artplayer-plugin-dash-control.js", + "sha256": "248aa1162ffb2480965f8e12d766ba6b7d2abfc2d80e65e8a6e8db6bdfa750c5", + "raw": 3450, + "gzip9": 1608, + "brotli6": 1504 + }, + { + "name": "artplayer-plugin-dash-control", + "version": "1.1.0", + "path": "dist/artplayer-plugin-dash-control.legacy.js", + "sha256": "248aa1162ffb2480965f8e12d766ba6b7d2abfc2d80e65e8a6e8db6bdfa750c5", + "raw": 3450, + "gzip9": 1608, + "brotli6": 1504 + }, + { + "name": "artplayer-plugin-dash-control", + "version": "1.1.0", + "path": "dist/artplayer-plugin-dash-control.mjs", + "sha256": "a29459436962e54efc3203d3264264291723593196461a6f116a684e53d7154f", + "raw": 6074, + "gzip9": 1893, + "brotli6": 1767 + }, + { + "name": "artplayer-plugin-document-pip", + "version": "1.1.0", + "path": "dist/artplayer-plugin-document-pip.js", + "sha256": "261d4ae84579c569ade1b1e7e91d51e3bd00c6efbea8c51a48b8283e0f4f3496", + "raw": 4624, + "gzip9": 1776, + "brotli6": 1593 + }, + { + "name": "artplayer-plugin-document-pip", + "version": "1.1.0", + "path": "dist/artplayer-plugin-document-pip.legacy.js", + "sha256": "8e36b658196dece391add21c249b735f3abfe4082fc968d3dbbbb1ae58a77b31", + "raw": 5356, + "gzip9": 2081, + "brotli6": 1901 + }, + { + "name": "artplayer-plugin-document-pip", + "version": "1.1.0", + "path": "dist/artplayer-plugin-document-pip.mjs", + "sha256": "ba1ae10a27740abc1c516470db8d03d45b88e3550180720bf3353864d629cca2", + "raw": 7106, + "gzip9": 2072, + "brotli6": 1885 + }, + { + "name": "artplayer-plugin-hls-control", + "version": "1.1.0", + "path": "dist/artplayer-plugin-hls-control.js", + "sha256": "7a6ce18a0b16f61f6149e0ea77efbb6e0503f997d39afe84271b59e366759e6d", + "raw": 3156, + "gzip9": 1439, + "brotli6": 1327 + }, + { + "name": "artplayer-plugin-hls-control", + "version": "1.1.0", + "path": "dist/artplayer-plugin-hls-control.legacy.js", + "sha256": "893a3de27f9ed02b4b61f03732aec03bfcaf50d02c9beb15cc8a5767ef9121a0", + "raw": 3182, + "gzip9": 1457, + "brotli6": 1346 + }, + { + "name": "artplayer-plugin-hls-control", + "version": "1.1.0", + "path": "dist/artplayer-plugin-hls-control.mjs", + "sha256": "5e665c994be0cd2c00538ac2e5f79e4fbda34083d4d04cccbe5d0047a9306f24", + "raw": 5158, + "gzip9": 1656, + "brotli6": 1532 + }, + { + "name": "artplayer-plugin-jassub", + "version": "1.1.0", + "path": "dist/artplayer-plugin-jassub.js", + "sha256": "271d5284e5246fbd04575526510b3e381e5e60d414c030acecce92fcf2e9b10a", + "raw": 16231, + "gzip9": 5354, + "brotli6": 5116 + }, + { + "name": "artplayer-plugin-jassub", + "version": "1.1.0", + "path": "dist/artplayer-plugin-jassub.legacy.js", + "sha256": "0726c96bf0df2aab2662ac8973bb7676a0ca7f8e4cb806aa44cb3ec9de296e64", + "raw": 16947, + "gzip9": 5639, + "brotli6": 5399 + }, + { + "name": "artplayer-plugin-jassub", + "version": "1.1.0", + "path": "dist/artplayer-plugin-jassub.mjs", + "sha256": "00a39303dd1eba1d78cf164e38dad359dc026bf57a3595175c48f30eb7f8f322", + "raw": 34349, + "gzip9": 10048, + "brotli6": 9589 + }, + { + "name": "artplayer-plugin-multiple-subtitles", + "version": "1.2.0", + "path": "dist/artplayer-plugin-multiple-subtitles.js", + "sha256": "c1cb0b511da88347165cc855185de9450a44835bb34bb802281ccdb854ef603c", + "raw": 13433, + "gzip9": 4913, + "brotli6": 4721 + }, + { + "name": "artplayer-plugin-multiple-subtitles", + "version": "1.2.0", + "path": "dist/artplayer-plugin-multiple-subtitles.legacy.js", + "sha256": "0b17644827e5b199afe8293093c44bfda571821014ff5b087c7c918c630dcc18", + "raw": 14099, + "gzip9": 5198, + "brotli6": 4993 + }, + { + "name": "artplayer-plugin-multiple-subtitles", + "version": "1.2.0", + "path": "dist/artplayer-plugin-multiple-subtitles.mjs", + "sha256": "9c664c8410849d9ff0da1febf1b86357e326b879cb479c8df8d70a1847c97c90", + "raw": 27666, + "gzip9": 6211, + "brotli6": 5931 + }, + { + "name": "artplayer-plugin-vast", + "version": "1.2.0", + "path": "dist/artplayer-plugin-vast.js", + "sha256": "72842ae0b4a44e44a080f88783c0c9bcd0b572fa0e946d817b2c36d960a08bfe", + "raw": 23307, + "gzip9": 6935, + "brotli6": 6667 + }, + { + "name": "artplayer-plugin-vast", + "version": "1.2.0", + "path": "dist/artplayer-plugin-vast.legacy.js", + "sha256": "4b88cec8d12844d639cc7703f88703136a4fe586781d9939bf2e3a0c93b42b60", + "raw": 23571, + "gzip9": 7041, + "brotli6": 6770 + }, + { + "name": "artplayer-plugin-vast", + "version": "1.2.0", + "path": "dist/artplayer-plugin-vast.mjs", + "sha256": "5a66a4b40bbeaa47cb307f9a40935c1a0a73eee880b4df4a4580568df7162576", + "raw": 31443, + "gzip9": 7860, + "brotli6": 7544 + }, + { + "name": "artplayer-plugin-vtt-thumbnail", + "version": "1.1.0", + "path": "dist/artplayer-plugin-vtt-thumbnail.js", + "sha256": "2d8e22cbd191bdac5a6c711b641590c2f8a90ba1aae185dd0e02a00baf000f8d", + "raw": 2325, + "gzip9": 1228, + "brotli6": 1133 + }, + { + "name": "artplayer-plugin-vtt-thumbnail", + "version": "1.1.0", + "path": "dist/artplayer-plugin-vtt-thumbnail.legacy.js", + "sha256": "ecbd0abe12c537687fb058de552c328c71ced71d911e454d0e37887192e9a291", + "raw": 2594, + "gzip9": 1342, + "brotli6": 1244 + }, + { + "name": "artplayer-plugin-vtt-thumbnail", + "version": "1.1.0", + "path": "dist/artplayer-plugin-vtt-thumbnail.mjs", + "sha256": "1f3d0f2bcd68bf69a22fcc3023f1e6ffd4a154099597d899c317cd04a3c28d3b", + "raw": 4408, + "gzip9": 1542, + "brotli6": 1448 + }, + { + "name": "artplayer-proxy-canvas", + "version": "1.1.0", + "path": "dist/artplayer-proxy-canvas.js", + "sha256": "ef489570e13f402f1a60eb256ce3900a0021a3d05699c2ba15adfaaeff184d4c", + "raw": 1927, + "gzip9": 944, + "brotli6": 876 + }, + { + "name": "artplayer-proxy-canvas", + "version": "1.1.0", + "path": "dist/artplayer-proxy-canvas.legacy.js", + "sha256": "7d25f21170c06d067aeaa1c8e79b15f2c0130a27cff1b410532d6c4ef4d2d45f", + "raw": 2210, + "gzip9": 1071, + "brotli6": 1001 + }, + { + "name": "artplayer-proxy-canvas", + "version": "1.1.0", + "path": "dist/artplayer-proxy-canvas.mjs", + "sha256": "406eb15d0194fadfcb2e9cb02aeb1281f1b0c42e66911106a3307c755b48e24c", + "raw": 3973, + "gzip9": 1209, + "brotli6": 1119 + }, + { + "name": "artplayer-proxy-mediabunny", + "version": "1.2.0", + "path": "dist/artplayer-proxy-mediabunny.js", + "sha256": "7d088c0abe2f3c1e2857cb0547405ce1e5588630f28e484a64211fc675322bbd", + "raw": 370208, + "gzip9": 93700, + "brotli6": 85708 + }, + { + "name": "artplayer-proxy-mediabunny", + "version": "1.2.0", + "path": "dist/artplayer-proxy-mediabunny.legacy.js", + "sha256": "327da5f1be221af6887efb4175c1b92e4e0c28838cae8107acca652a76bddccb", + "raw": 390185, + "gzip9": 97578, + "brotli6": 88846 + }, + { + "name": "artplayer-proxy-mediabunny", + "version": "1.2.0", + "path": "dist/artplayer-proxy-mediabunny.mjs", + "sha256": "9dec2077358ccc7e085c5d511b3c507265e3ea764b7d497b87c0eba199236001", + "raw": 817627, + "gzip9": 145209, + "brotli6": 130741 + }, + { + "name": "artplayer-tool-iframe", + "version": "1.1.0", + "path": "dist/artplayer-tool-iframe.js", + "sha256": "2ec257c8055a9448d12af3fecf1fae8ba58c06f47e85072d02c386cd258b0c86", + "raw": 2878, + "gzip9": 1108, + "brotli6": 1005 + }, + { + "name": "artplayer-tool-iframe", + "version": "1.1.0", + "path": "dist/artplayer-tool-iframe.legacy.js", + "sha256": "c0755d79f316cda71f045da86749648f95faf47c09180d525fb04bb753576d5f", + "raw": 3108, + "gzip9": 1211, + "brotli6": 1107 + }, + { + "name": "artplayer-tool-iframe", + "version": "1.1.0", + "path": "dist/artplayer-tool-iframe.mjs", + "sha256": "138fcad1c66d7180728a209e99c600ca585f7d8be9f8cb757bfd6ec71b3f0bb7", + "raw": 4231, + "gzip9": 1210, + "brotli6": 1097 + }, + { + "name": "artplayer-tool-thumbnail", + "version": "4.4.0", + "path": "dist/artplayer-tool-thumbnail.js", + "sha256": "f77419cc62eeaa45c0413f4b04d169f78178fd539443cbf7b1e5db4ad4c95c98", + "raw": 5984, + "gzip9": 2331, + "brotli6": 2147 + }, + { + "name": "artplayer-tool-thumbnail", + "version": "4.4.0", + "path": "dist/artplayer-tool-thumbnail.legacy.js", + "sha256": "f77419cc62eeaa45c0413f4b04d169f78178fd539443cbf7b1e5db4ad4c95c98", + "raw": 5984, + "gzip9": 2331, + "brotli6": 2147 + }, + { + "name": "artplayer-tool-thumbnail", + "version": "4.4.0", + "path": "dist/artplayer-tool-thumbnail.mjs", + "sha256": "0610fc05d3f5b207280fffcd0024411b53964d669fb09241c464eeda88b10570", + "raw": 9293, + "gzip9": 2779, + "brotli6": 2597 + } + ] +} diff --git a/refactor/changes/2026-09-10-BASE-06-performance.md b/refactor/changes/2026-09-10-BASE-06-performance.md new file mode 100644 index 000000000..e03ca813a --- /dev/null +++ b/refactor/changes/2026-09-10-BASE-06-performance.md @@ -0,0 +1,19 @@ +# BASE-06:性能与资源基线 + +日期 2026-09-10;分支 codex/compatible-modernization;起点 c7a375e1。 + +## 实现及测量 + +新增 performance.html/js,使用固定发布核心/chapter 和本地视频。两次前台重载各收集 12 个交错计时样本(每配置 1 预热+5 样本),真实播放推进后销毁;分别测 constructor、ready、play Promise 和 destroy,不用固定延迟声称媒体已就绪。 + +资源诊断独立于计时,临时追踪定时器/RAF、开启 USE_RAF=true、触发代理事件和销毁前的 pending resize。两轮各 6 组结果一致:DOM/实例/代理账本清空、原代理不再响应、RAF 停止;同时复现 BASE-PERF-01,销毁后的 debounce 触发 resize 并重新创建 notice timer。追踪器记录后自己的额外取消操作没有计入播放器清理结果。 + +新增独立验证/统计/比较工具、阈值说明、28 个已发布 JS 与 85 个工作区 JS 的压缩体积清单(21 库)。真实发布来源与工作区陈旧产物分开。浏览器报告和测量后的 host CIM 参数均留存;不声称已测内存/GC/GPU 泄漏或获得性能收益。同代码两轮 ready 中位数从约 30ms 到 13-15ms,恰说明需要多组配对比较。 + +详细结果、ID、环境、范围、阈值和复现见 [性能台账](../baselines/performance-coverage.md)、[浏览器原始数据](../baselines/performance.json) 和 [体积数据](../baselines/sizes.json)。BASE-PERF-01 已分配 CORE-17,关联 CORE-04/18;ENG-08/MOD-03 接续候选比较与改进。 + +## 验证与接续 + +两轮 errors/unhandled 和浏览器 error/warn 为空;新增 3 项 Node 测试包含数据无效、后台/假播放、清理失败、忽略预热、重大变慢、不同设备与体积漏项负例,真实发布压缩结果可重算。完整 ci:check、计划/链接、语法和 diff 检查通过。没有修改生产代码、依赖、声明或分发产物,不用历史异常要求候选继续出错。 + +本任务独立本地提交,主题含 BASE-06;不推送/发布。撤销提交恢复上一个基线服务和测试入口;历史报告由 Git 保留。下一任务 BASE-07:整合差异、vendored/外部依赖与风险,随后继续工程基础和首个 TS 试点。 diff --git a/refactor/fixtures/performance.html b/refactor/fixtures/performance.html new file mode 100644 index 000000000..b1a33cc73 --- /dev/null +++ b/refactor/fixtures/performance.html @@ -0,0 +1,15 @@ + + + +
Keep this tab visible. Timing samples are separate from instrumented resource probes.
+ +Ready
+ + + + + + diff --git a/refactor/fixtures/performance.js b/refactor/fixtures/performance.js new file mode 100644 index 000000000..8d70a6d39 --- /dev/null +++ b/refactor/fixtures/performance.js @@ -0,0 +1,166 @@ +/* global Artplayer, artplayerPluginChapter */ +(() => { + const container = document.querySelector('.player') + const status = document.querySelector('#status') + const now = () => performance.now() + const options = chapter => ({ container, url: '/assets/sample/video.mp4', muted: true, plugins: chapter ? [artplayerPluginChapter({ chapters: [{ start: 0, end: 10, title: 'First' }, { start: 10, end: Infinity, title: 'Second' }] })] : [] }) + function waitFor(test, timeout = 12000) { + const started = now() + return new Promise((resolve, reject) => { + const poll = () => { + if (test()) resolve() + else if (now() - started > timeout) reject(new Error('State timeout')) + else requestAnimationFrame(poll) + } + poll() + }) + } + function timers() { + const original = Object.fromEntries(['setTimeout', 'clearTimeout', 'setInterval', 'clearInterval', 'requestAnimationFrame', 'cancelAnimationFrame'].map(name => [name, window[name]])) + const active = new Map() + const late = [] + let destroyed = false + const capture = (kind, callback, delay, args) => { + if (typeof callback !== 'function') throw new Error('Timer probe only supports function callbacks') + let handle + const wrapped = function (...values) { + if (kind !== 'interval') active.delete(`${kind}:${handle}`) + if (destroyed) late.push({ kind, delay }) + return callback.apply(this, values) + } + handle = kind === 'raf' ? original.requestAnimationFrame.call(window, wrapped) : original[kind === 'timeout' ? 'setTimeout' : 'setInterval'].call(window, wrapped, delay, ...args) + active.set(`${kind}:${handle}`, { kind, delay }) + return handle + } + window.setTimeout = (callback, delay = 0, ...args) => capture('timeout', callback, delay, args) + window.setInterval = (callback, delay = 0, ...args) => capture('interval', callback, delay, args) + window.requestAnimationFrame = callback => capture('raf', callback, null, []) + for (const clear of ['clearTimeout', 'clearInterval']) window[clear] = (handle) => { + active.delete(`timeout:${handle}`) + active.delete(`interval:${handle}`) + return original[clear].call(window, handle) + } + window.cancelAnimationFrame = (handle) => { + active.delete(`raf:${handle}`) + return original.cancelAnimationFrame.call(window, handle) + } + return { + snapshot: () => [...active.values()], late, + markDestroyed: () => { destroyed = true }, + wait: ms => new Promise(resolve => original.setTimeout.call(window, resolve, ms)), + restore: () => { + // Probe-owned cleanup only after recording; never count it as library cleanup. + for (const key of active.keys()) { + const [kind, handle] = key.split(':') + original[kind === 'raf' ? 'cancelAnimationFrame' : kind === 'interval' ? 'clearInterval' : 'clearTimeout'].call(window, Number(handle)) + } + Object.assign(window, original) + active.clear() + }, + } + } + document.querySelector('#run').onclick = async () => { + document.querySelector('#run').disabled = true + const report = { + kind: 'performance', + environment: { userAgent: navigator.userAgent, language: navigator.language, hardwareConcurrency: navigator.hardwareConcurrency, deviceMemory: navigator.deviceMemory ?? null, devicePixelRatio, viewport: { width: innerWidth, height: innerHeight }, visibility: document.visibilityState }, + scripts: [...document.scripts].map(script => new URL(script.src).pathname), + samples: [], resources: [], errors: [], unhandled: [], visibilityChanges: [], + } + const onError = event => report.errors.push(event.message) + const onUnhandled = event => report.unhandled.push(String(event.reason)) + const onVisibility = () => report.visibilityChanges.push(document.visibilityState) + addEventListener('error', onError) + addEventListener('unhandledrejection', onUnhandled) + document.addEventListener('visibilitychange', onVisibility) + let art + const originalRaf = Artplayer.USE_RAF + try { + if (document.visibilityState !== 'visible') throw new Error('Keep benchmark tab visible') + if (originalRaf !== false) throw new Error('Unexpected published default USE_RAF') + // Interleave configurations, retaining one warm-up per configuration separately. + for (let round = 0; round < 6; round++) { + for (const chapter of [false, true]) { + status.textContent = `Timing ${round + 1}/6: ${chapter ? 'core + chapter' : 'core'}` + const started = now() + art = new Artplayer(options(chapter)) + const constructorMs = now() - started + await waitFor(() => art.isReady) + const readyMs = now() - started + const playbackStarted = now() + await art.play() + const playResolvedMs = now() - playbackStarted + const startTime = art.currentTime + await waitFor(() => art.currentTime >= startTime + 0.15) + const playbackObservedMs = now() - playbackStarted + const mediaProgress = art.currentTime - startTime + art.pause() + const nodes = container.querySelectorAll('*').length + const proxyCleanupEntries = art.events.destroyEvents.size + const video = art.video + const videoWidth = video.videoWidth + const destroyStarted = now() + art.destroy() + const destroyMs = now() - destroyStarted + report.samples.push({ configuration: chapter ? 'chapter' : 'core', warmup: round === 0, round, constructorMs, readyMs, playResolvedMs, playbackObservedMs, mediaProgress, videoWidth, nodes, proxyCleanupEntries, destroyMs, + afterDestroy: { nodes: container.querySelectorAll('*').length, instances: Artplayer.instances.length, proxyCleanupEntries: art.events.destroyEvents.size, paused: video.paused, sourceAttribute: video.getAttribute('src') } }) + art = null + } + } + // Instrumentation is deliberately excluded from the timing samples above. + for (let round = 0; round < 3; round++) { + for (const chapter of [false, true]) { + status.textContent = `Resources ${round + 1}/3: ${chapter ? 'core + chapter' : 'core'}` + const probe = timers() + let destroyed = false + let lateResizeEvents = 0 + let proxyCalls = 0 + let frames = 0 + try { + Artplayer.USE_RAF = true + art = new Artplayer(options(chapter)) + art.on('raf', () => frames++) + art.on('resize', () => { if (destroyed) lateResizeEvents++ }) + art.proxy(document, 'art-baseline-resource', () => proxyCalls++) + await waitFor(() => art.isReady) + await art.play() + await waitFor(() => frames >= 2) + art.notice.show = 'Resource probe' + document.dispatchEvent(new Event('art-baseline-resource')) + // Controlled pending debounce before teardown, not a trusted user resize. + window.dispatchEvent(new Event('resize')) + const before = { timers: probe.snapshot(), proxyCleanupEntries: art.events.destroyEvents.size, frames, proxyCalls } + art.destroy() + destroyed = true + probe.markDestroyed() + const immediatelyAfter = probe.snapshot() + const atDestroyFrames = frames + document.dispatchEvent(new Event('art-baseline-resource')) + const waitStarted = now() + await probe.wait(350) + report.resources.push({ configuration: chapter ? 'chapter' : 'core', round, useRaf: true, before, immediatelyAfter, + after: { observedMs: now() - waitStarted, timers: probe.snapshot(), lateCallbacks: [...probe.late], lateResizeEvents, framesAfterDestroy: frames - atDestroyFrames, proxyCalls, proxyCleanupEntries: art.events.destroyEvents.size, nodes: container.querySelectorAll('*').length, instances: Artplayer.instances.length } }) + art = null + } + finally { + if (art && Artplayer.instances.includes(art)) art.destroy() + probe.restore() + Artplayer.USE_RAF = originalRaf + } + } + } + } + catch (error) { report.errors.push(error.message) } + finally { + if (art && Artplayer.instances.includes(art)) art.destroy() + Artplayer.USE_RAF = originalRaf + removeEventListener('error', onError) + removeEventListener('unhandledrejection', onUnhandled) + document.removeEventListener('visibilitychange', onVisibility) + } + report.remainingInstances = Artplayer.instances.length + document.querySelector('#result').textContent = JSON.stringify(report, null, 2) + const response = await fetch('/reports/performance', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(report) }) + status.textContent = response.ok ? `Saved ${report.samples.length} timing samples and ${report.resources.length} resource probes; errors ${report.errors.length}` : 'Save failed' + } +})() diff --git a/refactor/plan.md b/refactor/plan.md index 54b8bf712..7b794ec4b 100644 --- a/refactor/plan.md +++ b/refactor/plan.md @@ -4,7 +4,7 @@ 基线:`40fcda6a37d0049d42e49c1e64e70d4fd9ba5f7f`。总任务 214 项,范围 22 个包及工作区/示例。 -状态:todo 192 / doing 0 / blocked 0 / done 22 / deferred 0。风险 L/M/H 表示兼容风险,不表示工期。 +状态:todo 191 / doing 0 / blocked 0 / done 23 / deferred 0。风险 L/M/H 表示兼容风险,不表示工期。 前置依赖是启动条件;验收是完成条件。任务可以继续拆分,但不能复用或悄悄删除旧 ID。 @@ -65,8 +65,8 @@ | BASE-03 | workspace