浏览器无法直接读取bios或windows电源计划名称,但可通过navigator.getbattery()状态、performance.now()定时偏差、document.hidden与screen.orientation.type异常联动等特征交叉判断是否处于系统级节电模式。

如何检测当前硬件电源管理模式
浏览器无法直接读取 BIOS 或 Windows 电源计划名称,但可通过 navigator.getBattery() 和系统行为特征交叉判断。关键不是“知道叫什么”,而是“判断是否正在节电”。
-
navigator.getBattery()返回对象中,若battery.level ,大概率处于系统级低电量节流状态(如 Windows 电池模式 + 节能计划) - 用
performance.now()连续测量两次setTimeout(fn, 0)的实际间隔:若平均超过 8ms(Chrome 正常约 0.5–4ms),说明主线程已被后台节流 - 监听
document.hidden变化的同时检查screen.orientation.type—— 某些 OEM 厂商在电池模式下会强制锁定屏幕方向并抑制 visibilitychange 触发,这是节电驱动干预的信号
主线程休眠时该停哪些 HTML 工具函数
不是所有定时逻辑都需要停,重点是那些“停了不影响功能,但不停就白耗电”的任务。比如语法高亮、实时预览、自动保存这类依赖高频 DOM 操作的函数,在页面不可见+低电量时继续跑,只会让风扇转得更响。
- 停掉
requestAnimationFrame驱动的 canvas 动画或滚动同步,改用visibilitychange事件恢复 - 把
setInterval(checkForChanges, 500)替换为self.setInterval并移入 Web Worker(主线程节流不影响 Worker 内部调度) - 禁用
WebSocket心跳重连逻辑,改用navigator.sendBeacon()每 30 秒上报一次轻量状态,避免连接维持开销
Web Worker 中如何适配不同电源模式
Worker 本身不感知页面可见性,但可以接收主线程传来的电源状态信号,并据此调整自身行为。别在 Worker 里重复检测电池,那会触发跨线程权限错误。
- 主线程通过
worker.postMessage({ type: 'POWER_STATE', level: 0.15, charging: false })主动推送状态 - Worker 内部用
self.setInterval替代setInterval,且周期按 level 动态缩放:level - 避免在 Worker 中调用
fetch或importScripts—— 低电量下网络栈可能被系统降频,容易超时失败
为什么不能只靠 visibilitychange 切换前后台
因为 visibilitychange 在低电量+后台标签页场景下经常失效或延迟触发。Windows 系统级节流、OEM 电池驱动、甚至 Chrome 的 Background Tabs Throttling 都会让这个事件“迟到”甚至“丢包”。
- 单独监听
visibilitychange时,document.hidden === true可能持续数分钟才触发,期间定时器已拉长到 10s 以上 - 必须叠加
performance.now()时间戳校验:每次定时回调开头记录时间,若与上次差值 > 5000ms,立即认为进入节流状态并降级逻辑 - 某些设备(如 Surface Pro 系列)在电池模式下会静默丢弃
visibilitychange,但pagehide仍可捕获,建议同时监听二者
navigator.wakeLock.request() 锁定执行节奏,否则一进低电量就彻底失步。前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











