visibilitychange 是宏任务事件,由浏览器页面可见性管理模块触发并推入宏任务队列,需等待当前宏任务及所有微任务执行完毕后才执行回调,不打断同步代码,且不受后台标签页节流影响。

事件循环本身不直接处理 visibilitychange 事件,而是为它的触发和响应提供执行环境。这个事件由浏览器的“页面可见性管理模块”在状态变化时主动调度进事件循环的任务队列,再由事件循环按规则分发执行。
visibilitychange 是宏任务级别的事件
当用户切走标签页、最小化窗口或锁屏时,浏览器内核检测到可见性状态变更(如从 visible 变为 hidden),会将一个 visibilitychange 事件对象推入宏任务队列(不是微任务)。它和其他 DOM 事件(如 click、load)一样,遵循标准事件循环流程:
- 当前宏任务(如初始化脚本)执行完毕
- 清空全部微任务(
Promise.then、MutationObserver等) - 从宏任务队列中取出一个任务——此时若
visibilitychange已入队,就会被取出并执行其监听器回调
它不会打断正在运行的同步代码
即使页面瞬间被切走,visibilitychange 也不会中断当前执行栈中的 JS。例如:
Java开发手册规约集合,基于阿里巴巴Java开发手册(嵩山版)。 涵盖7大维度:编程规约、异常日志、单元测试、安全规约、MySQL数据库、工程结构、设计规约。 当用户需要:(1) 编写或审查Java代码 (2) 检查命名/代码规范 (3) 处理异常和日志 (4) 编写单元测试 (5) 安全编码 (6) 数据库设...
console.log('start');
while (Date.now() - start <p>这段代码执行期间用户切走标签页,<code>visibilitychange</code> 回调仍需等到整个 <code>while</code> 循环结束、微任务清空后才执行。它<strong>不具有实时中断能力</strong>,也不属于高优先级异步机制(如 <code>requestAnimationFrame</code>)。</p><h3>后台标签页会影响事件循环节奏</h3><p>现代浏览器会对隐藏标签页进行节流优化,这间接影响 <code>visibilitychange</code> 相关逻辑的后续行为:</p>
-
setTimeout和setInterval在hidden状态下可能被降频(如最低 1s 一次) -
requestAnimationFrame基本暂停,不再每帧触发 - 但
visibilitychange事件本身不受节流影响:只要状态真实变化(切回、解锁、还原窗口),事件就立即入队并尽快执行
与播放控制等操作的配合要点
在 visibilitychange 回调里调用 video.play() 或 pause() 是安全的,但要注意:
- 恢复播放时,
play()可能因自动播放策略被拒绝——这不是事件循环问题,而是浏览器策略限制;建议首次播放由用户手势(如点击按钮)触发,后续切回时再调用更可靠 - 避免在回调中执行长任务(如遍历大数组、解析大 JSON),否则会延迟渲染、影响切回后的首帧体验
- 不需要手动清理定时器再重建,可直接修改
clearTimeout/clearInterval,它们在事件循环中是同步完成的
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










