fix(display): 大屏数字不再依赖帧回调(被遮挡时卡住)+ Console 关遮挡节流 + resync 冷却期排队;版本 dev_0.5.13

现场:清空本组后,大屏上的「单位总分」要等几十秒才降下来。

根因不在「清空」这条路:服务端在同一个事务里就把流水作废重写、算出整张榜单并推送,
与「撤销发布」逐条同构(results_clear.go / scoring.go:1057)。真正卡住的是那一格数字的
画法 —— 它用 requestAnimationFrame 逐帧滚动,而 Chromium 对被遮挡 / 后台的窗口会停掉
帧生产:数字停在旧值,卡多久 = 被遮挡多久,与后台算分无关。全场只有「单位总分」是滚动
显示的,奖牌榜 / 分项成绩 / 实时赛况都是纯文本,所以只有它看起来会延迟。

- 新增 web/src/display/animatedNumber.ts:缓出插值、兜底时长、是否直接对齐抽成纯函数;
  进度越界的晚到单帧直接落到目标值(对应「窗口恢复可见瞬间跳到新值」)
- AnimatedNumber.vue:加 duration+400ms 的兜底计时器(帧一个都不来也最迟约 1.3s 对齐到
  新值);visibilitychange 变可见 / window focus 时立刻对齐,不再补滚一遍过时动画;
  卸载时摘掉监听(大屏是长跑窗口)
- console/main/index.js:主进程在 app ready 之前追加
  disable-backgrounding-occluded-windows / disable-renderer-backgrounding;
  两个 Console 窗口补 backgroundThrottling: false,与大屏窗口同口径
- web/src/shared/realtime.ts:requestResync() 冷却期内排队而不是丢弃 —— 原先丢掉之后
  本地版本已经推进,心跳的 data.version > currentVersion 再也发现不了缺口,
  那一版该做的重拉会永久缺失

测试 +11 例(display 9 / shared 2),含「命令行开关必须位于 app.whenReady() 之前」的位置断言。
四套自检 ×2 全绿(finalcheck_0513.log:前端 985 例 / Console 96 例 / 服务端 14 包,EXIT=0)。

无数据库迁移;已有成绩、名次、积分、榜单与导出件一个数字都不变。
文档:docs/升级说明.md 新增 dev_0.5.13 一节;docs/常见问题.md 新增 Q103。
This commit is contained in:
AskaEth committed 2026-09-17 02:02:07 +08:00
1 parent b29b2b390a
commit 19e5630b39
13 files changed
+401 -26

No files matched your search

+37
View File
@@ -6,6 +6,43 @@
---
## dev_0.5.13
### 一句话
**纯界面 / 宿主程序的小修,没有任何数据迁移:升级后不用重配、不用重新导入规则包**,已有的成绩、名次、积分、榜单与导出件**一个数字都不变**。这一版修一处**现场看得见的延迟**:**大屏上的「单位总分」要等几十秒才更新**(清空本组、发布、调整之后都可能遇到)。
### ① 修:「大屏上的单位总分等几十秒才降」
**先说清楚它不是什么**:不是「清空没生效」、也不是「分数算错了」——**分数在服务端是当场就变了的**,数据库、榜单接口、导出件从你点下确认的那一刻就已经是新值。**卡住的只是大屏上那一格数字的画法。**
**真正的原因**:大屏上「单位总分」那一格是**逐帧滚动**过去的(一帧一帧把数字从旧值滚到新值),而浏览器对**被别的窗口盖住的窗口**会**停掉逐帧绘制**——数字就停在旧值上,**卡多久取决于被盖住多久**,跟后台算分一点关系都没有。所以你会看到「等几十秒才降」,而且**把盖住大屏的窗口挪开以后,数字是「啪」地一下跳到新值**,不是慢慢滚过去。
> 为什么只有这一格?因为**全场只有「单位总分」这个数字是滚动显示的**,奖牌榜、分项成绩、实时赛况里的数字都是直接写上去的——这也是为什么现场感觉「别的都立刻变、只有总分不动」。
**现在会怎样**:
1. 就算一帧都画不出来,**最迟约 1.3 秒**数字也会直接落到新值(不再无限期停在旧值);
2. 大屏窗口**重新露出来 / 重新被点活**时,数字**立刻**是正确值,**不会再补滚一遍过时动画**;
3. 宿主程序(Console)同时关掉了浏览器对「被遮挡 / 后台」窗口的降频,大屏更不容易掉帧。
### ② 顺带修:偶发「某一版变更漏掉、之后一直没补上」
大屏与管理面板在**短时间内连续发生多次变化**时,会向服务端要一次「补数据」。原先这个请求**在 3 秒冷却期内会被直接丢掉**,而界面此时已经认为「这一版处理过了」——于是该补的那一次**不会再补**,要等下一条无关的变化才顺带修正(现场表现可能是某块榜单的内容停在几秒前的样子)。现在改成**排队**:冷却一过立刻补发,不会再漏。
### ③ 升级后 5 分钟核对
1. 打开大屏的**积分榜**页,随便做一次会让分数变化的操作(例如「清空本组」,或发布一批成绩),**清空后不要动鼠标**:那一格数字应当在 **1~2 秒内**落到新值;
2. 故意拿一个窗口**把大屏窗口完全盖住 10 秒**,再挪开:数字应当**立刻就是正确值**(不是从旧值滚一遍过来);
3. 奖牌榜、分项成绩、实时赛况本来就是直接显示,行为与升级前一致;
4. 其余照旧:**不需要重新导入规则包、不需要重配任何东西**;已有成绩、榜单与导出件**一个字不变**。
### ④ 详细说明在哪
《常见问题》Q103(大屏上的分数为什么过一会儿才变 / 后来一直不变了)。
---
## dev_0.5.12
### 一句话