瀏覽器頁(yè)面處于不活躍狀態(tài)時(shí)setInterval不定時(shí)執(zhí)行
1.問(wèn)題背景
頁(yè)面建立webSocket并設(shè)置定時(shí)保活機(jī)制,切換到后臺(tái)或其他標(biāo)簽頁(yè)一段時(shí)間后,定時(shí)器未按時(shí)調(diào)用,導(dǎo)致?;畛瑫r(shí),ws closed
2.原因
當(dāng)頁(yè)面變?yōu)榉腔顒?dòng)狀態(tài)時(shí),WebKit 會(huì)自動(dòng)采取措施來(lái)節(jié)省電量:
-
requestAnimationFrame停止。 - CSS 和 SVG 動(dòng)畫(huà)被暫停。
- 計(jì)時(shí)器受到限制。
頁(yè)面變?yōu)榉腔顒?dòng)狀態(tài)(不是用戶(hù)的主要焦點(diǎn))的情況有多種,例如:
- 用戶(hù)切換到不同的選項(xiàng)卡。
- 用戶(hù)切換到不同的應(yīng)用程序。
- 瀏覽器窗口最小化。
- 瀏覽器窗口可見(jiàn)但不是焦點(diǎn)窗口。
- 瀏覽器窗口位于另一個(gè)窗口的后面。
- 窗口所在的空間不是當(dāng)前空間。
3.解決方案
使用 Web Workers??梢宰尀g覽器窗口在非激活狀態(tài)(或者最小化)也讓setTimeout、setInterval有效不休眠的功能。
而且webWorkers還可以解決一個(gè)頁(yè)面存在多個(gè)定時(shí)器時(shí)候間隔時(shí)間誤差較大的問(wèn)題。
4.交互狀態(tài)
對(duì)于 Web 開(kāi)發(fā)人員,需要考慮三種交互狀態(tài):
- 當(dāng)用戶(hù)主動(dòng)與內(nèi)容交互時(shí)。
- 當(dāng)頁(yè)面位于最前面,但用戶(hù)沒(méi)有與之交互時(shí)。
- 當(dāng)頁(yè)面不是最前面的內(nèi)容時(shí)。
頁(yè)面可見(jiàn)性監(jiān)聽(tīng):
- 頁(yè)面可見(jiàn)性 API提供了一種方法來(lái)響應(yīng)頁(yè)面轉(zhuǎn)換到后臺(tái)或前臺(tái)。這是避免在頁(yè)面處于后臺(tái)時(shí)更新 UI
-
blur只要頁(yè)面不再聚焦,就會(huì)發(fā)送事件。在這種情況下,頁(yè)面可能仍然可見(jiàn),但它不是當(dāng)前聚焦的窗口。
5.參考:
(1)How Web Content Can Affect Power Usage https://webkit.org/blog/8970/how-web-content-can-affect-power-usage/#:~:text=Timers%20are%20throttled
(2)當(dāng)瀏覽器切換到其他標(biāo)簽頁(yè)或者最小化時(shí),你的js定時(shí)器還準(zhǔn)時(shí)嗎?https://juejin.cn/post/6899796711401586695