低电量下setTimeout/setInterval变慢是浏览器主动节流所致,应使用performance.now()校验真实间隔,改用事件驱动+时间戳兜底、requestIdleCallback或SSE替代轮询;rAF卡顿时需结合visibilitychange与battery.level降级,优先CSS动画;后台标签页需双判可见性与电量,并用sendBeacon保活。
HTML 本身没有函数,也不会因低电量“受限”——真正受影响的是浏览器对 JavaScript 定时器、渲染和后台执行的节流策略。
现代浏览器(Chrome、Edge、Safari)在系统报告低电量时,会主动拉长 setTimeout 和 setInterval 的实际执行间隔,常见现象是本该 100ms 触发一次的轮询,变成 500ms 甚至 2s 才执行。这不是代码 bug,而是浏览器主动降频保电。
performance.now() 校验真实耗时:在定时器回调开头记录时间戳,与上一次执行时间差对比,若远超预期,说明已被节流navigator.sendBeacon 成功后再启动下一轮setInterval 实现心跳或轮询逻辑;优先考虑 requestIdleCallback(需配合 timeout 参数防饿死)或服务端 SSE 推送requestAnimationFrame 在低电量+页面不可见时可能被暂停或大幅降低帧率,导致动画冻结、拖拽响应迟滞。它不报错,只“静默降频”,最难排查。
document.hidden 为 true 且 navigator.getBattery?.().level < 0.2 时,应主动降级动画逻辑requestAnimationFrame 驱动关键交互反馈(如按钮按压态),改用 CSS transition + classList.toggle,这类样式变更由渲染管线直接处理,不受 JS 调度节流影响performance.now() 计算 delta time,而非假设每帧 16ms,避免累积误差能,但行为差异极大:Chrome 会把后台标签页的定时器最小间隔拉长到 1000ms,Firefox 更激进(4s),Safari 则可能完全暂停 JS 执行。这不是规范要求,而是各浏览器电源策略的实际落地。
立即学习“前端免费学习笔记(深入)”;
setInterval(fn, 100) 在后台仍有效;改用页面可见性 + 电池状态双判断,document.addEventListener('visibilitychange', ...) 中恢复/暂停逻辑navigator.sendBeacon() 发送,它不依赖 JS 线程活跃,即使页面已进入后台也能发出请求self.setInterval 相对稳定,但也要注意:Android WebView 和部分 iOS WKWebView 仍可能对其施加后台限制最容易被忽略的一点:低电量策略不是统一开关,而是分层生效的——系统级省电(如 Windows 电池限制模式)、浏览器级节流(Chrome 的后台标签页冻结)、页面级响应(navigator.getBattery() 监听)三者叠加,任何一层没适配,都可能导致功能“看似正常实则失效”。