页面切到后台时应暂停动画、定时器等以节省资源,通过监听document.visibilityState和visibilitychange事件精准控制;隐藏时调用cancelAnimationFrame、clearTimeout等停止任务,显示后按需重建状态;现代浏览器可结合Page Lifecycle API(如pagehide、freeze)做更精细管理。

页面切到后台或标签页不可见时,BOM 动画、轮询、定时器等若继续运行,会白白消耗 CPU 和电池。浏览器提供了原生机制来感知可见性状态,配合 BOM 相关 API 可以实现精准的性能优化。
监听 visibilitychange 事件
document.visibilityState 和 visibilitychange 是最直接的页面可见性判断方式:
-
visibilityState 返回
'visible'、'hidden'、'prerender'或'unloaded',主流用前两个 - visibilitychange 在用户切换标签页、最小化窗口、锁屏等场景下触发,时机可靠且无需轮询
- 该事件挂载在
document上,不是 window,注意别写错对象
暂停动画与定时任务
一旦检测到页面隐藏,应主动停止依赖视觉更新的逻辑:
- 调用
cancelAnimationFrame(id)终止正在运行的 rAF 动画循环 - 清除
setTimeout/setInterval(尤其避免未清理的轮询请求) - 暂停
IntersectionObserver、ResizeObserver等观察器(可调用unobserve()或disconnect()) - 若使用 WebSocket 或长连接,可考虑暂时关闭重连逻辑,或降级为低频心跳
恢复时按需重建状态
页面重新 visible 后,不建议直接 resume 所有旧任务,而应评估是否需要重新初始化:
- 滚动位置、表单输入等用户状态通常保留,无需重置
- 动画帧序号、计时器偏移量等中间状态可能已失效,应重置再启动
- 对于数据轮询,可记录最后成功时间,恢复后检查是否需补漏(如“离线期间是否有新消息”)
- 避免在
visibilitychange回调中执行耗时操作,必要时用requestIdleCallback延后处理
结合 Page Lifecycle API(现代补充)
Chrome 88+ 支持更精细的生命周期事件,如 freeze、resume、pageshow、pagehide,它们比 visibilitychange 更底层:
-
pagehide触发时,页面可能被缓存(bfcache),此时 DOM 仍存活但 JS 执行受限 -
freeze表示页面已被冻结,JS 完全暂停,适合做最终清理 - 兼容性要求高时,仍以
visibilitychange为主,pagehide作增强
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











