一、浏览器标签切后台休眠带来的直播问题
很多 HLS 直播业务,用户打开直播页面之后,切到别的浏览器标签页、最小化浏览器窗口,一段时间切回来,直播画面卡住不动,不再更新。
很多开发第一反应怀疑 M3U8 流、CDN 问题,实际根源是现代浏览器的页面节流、休眠策略。当页面不可见,浏览器会降低、限制页面定时器、XHR 网络请求,节省 CPU 与电量。hls.js 内部用来刷新 M3U8 清单的定时器被浏览器冻结,不再请求新分片,直播画面静止。
很多新手做直播页面,完全没有处理visibilitychange页面可见性事件,页面切后台之后完全不做处理。现象只发生在标签页后台驻留之后,前台一直打开页面不会复现,日常简单测试很难发现。
而且不同浏览器策略不一样:Chrome、Edge、Safari 对后台页面的限制强度各不相同,Safari 移动端限制会更加严格。
调试页面后台休眠造成直播卡顿的问题,我会使用 m3u8live.cn 网页调试工具做对照:页面一直处于前台,直播持续正常;切到后台一段时间切回来,观察是否出现画面静止,区分是流本身问题还是浏览器后台策略。
二、页面后台休眠典型现象
现象 1:页面切后台放几分钟,切回前台直播画面静止,不会自动继续播放
M3U8 清单不再定时请求,没有新分片下载。手动刷新页面之后恢复正常。
现象 2:只是直播会复现,点播播放不会复现
点播一次性加载全部清单,不需要轮询刷新 M3U8;直播需要定时器定时拉取最新清单,定时器被冻结直接受影响。
现象 3:移动端浏览器限制比 PC 端更严格
手机浏览器切后台,页面更容易被浏览器休眠冻结,PC 上不容易复现,手机一测就出现。
现象 4:不是必现,和设备 CPU、电池省电模式有关
开启省电模式之后,浏览器后台页面限制会进一步加强,休眠现象更容易触发。
三、简单的业务处理方案
- 监听
visibilitychange页面可见性事件: 当document.visibilityState === 'hidden'页面切后台,调用hls.stopLoad()停止分片加载,节省带宽; 当页面重新变为visible切回前台,重新恢复拉流播放。
不要什么都不做,任由浏览器冻结定时器;也不要后台还继续疯狂拉取分片,浪费用户流量。
- 不要依靠 setInterval 定时器自己写 M3U8 轮询,尽量交给 hls.js 内部管理;hls.js 内部也会受浏览器后台节流影响,依旧需要 visibilitychange 做干预。
- 移动端测试,一定要模拟切后台操作,不能全程页面保持在前台做冒烟测试。
四、排查简单步骤
第一步,直播 M3U8 地址粘贴网页调试工具,页面保持前台持续播放,确认直播流本身没问题。 第二步,把浏览器标签切到其他页面,后台等待 2‑5 分钟,切回来,观察画面是否卡住。
- 如果工具页面同样复现后台卡住:属于浏览器本身后台节流策略,业务代码必须做 visibilitychange 事件处理;
- 如果工具页面后台正常,业务页面卡住:排查业务页面的定时器、播放器后台逻辑。
五、开发避坑提醒
❌误区:直播页面不需要处理页面可见性事件,hls.js 会全部自动搞定。浏览器后台会冻结定时器,hls.js 也逃不开浏览器底层限制。 ✅正确思路:监听 visibilitychange,后台停止加载,切回前台恢复播放,兼顾播放体验和用户流量消耗。
六、总结
浏览器页面切到后台会触发页面节流、定时器冻结,HLS 直播依赖定时刷新 M3U8 清单,后台驻留之后容易出现画面静止。这个问题前台测试很难复现,移动端省电模式下更容易出现。不能完全依赖 hls.js 自动处理,业务需要监听 visibilitychange 可见事件,后台停止拉流,切回前台再恢复。借助网页调试工具复现后台驻留场景,区分故障是浏览器策略还是业务逻辑,规避线上用户切后台之后直播卡住的问题。