欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

瀏覽器切換到其他標簽頁或最小化js定時器是否準時測試

 更新時間:2022年07月12日 15:52:33   作者:zouwowo  
這篇文章主要為大家介紹了瀏覽器切換到其他標簽頁或最小化是js定時器是否準時的測試詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

前言

這是我最近開發(fā)碰到的一個問題,本文是我測試出來的實踐結(jié)果,供大家參考。

關于js定時器,setInterval和setTimeout,作為我們?nèi)粘i_發(fā)經(jīng)常使用到的方法,大家一定非常熟悉。比如下面一個例子:

setInterval(() => {
  console.log('1');
}, 500);

作為剛學前端沒多久的新人也能知道,這段代碼就是每過500ms打印一次1(實際運行還需要考慮js的宏任務和微任務的執(zhí)行時間,定時器的間隔時間是500ms,但是定時器中的方法觸發(fā)可能需要在宏任務隊列中排隊,不一定會在500ms的時候觸發(fā),關于Event Loop的基礎內(nèi)容不在本文討論之內(nèi))。

但是如果你把瀏覽器從當前頁面切換到另一個標簽頁,或者把瀏覽器最小化了,這時候,這個頁面定時器的間隔時間還是500ms?

本文將測試setInterval、setTimeout、requestAnimationFrame這三個方法在瀏覽器可見以及不可見狀態(tài)下的表現(xiàn),我的測試瀏覽器以及版本是谷歌(86.0.4240.193),火狐(81.0.2),ie11。

瀏覽器可見和不可見狀態(tài)

瀏覽器的可見和不可見狀態(tài)的切換會觸發(fā)visibilitychange事件,我們可以通過監(jiān)聽這個事件來判別瀏覽器的可見狀態(tài)。

document.addEventListener("visibilitychange", function() {
  console.log(document.visibilityState);
});

document.visibilityState有三個值

  • hidden:頁面徹底不可見。
  • visible:頁面至少一部分可見。
  • prerender:頁面即將或正在渲染,處于不可見狀態(tài)。 這里重點關注hidden這個值,當我們?yōu)g覽器切換當前頁面到另外一個標簽頁或者把瀏覽器最小化的時候,document.visibilityState就會是hidden值。我們也可以使用document.hidden,它返回一個布爾值,為true的時候,說明當前瀏覽器是不可見狀態(tài)。

關于visibilitychange的細節(jié)可以看阮一峰老師的這篇文章 Page Visibility API 教程。

setInterval

我們先來測試setInterval,代碼如下

<button id="btn">開始計時</button>
// 兼容ie寫法
document.getElementById('btn').addEventListener('click', function() {
  setInterval(function() {
    const myDate = new Date();
    const currentDate = myDate.getMinutes() + '分'+ myDate.getSeconds() + '秒' + myDate.getMilliseconds() + '豪秒';
    // 每次循環(huán)打印當前時間
    console.log(currentDate);
  }, 500);
});
// 瀏覽器可見狀態(tài)切換事件
document.addEventListener('visibilitychange', function() { 
  if(document.hidden) {
    console.log('頁面不可見');
  }
});

定時器間隔是500ms,先來看下谷歌瀏覽器

我們發(fā)現(xiàn),當頁面不可見之后,定時器的間隔變成了1s。 接下來,我們把定時器間隔改成2s來試下。

前后間隔時間一致。

接下來測試一下火狐和ie。這里列出的圖片都是500ms和2s的例子。

ie瀏覽器

經(jīng)過我大量的測試,可以得出結(jié)論,谷歌瀏覽器中,當頁面處于不可見狀態(tài)時,setInterval的最小間隔時間會被限制為1s。火狐瀏覽器的setInterval和谷歌特性一致,但是ie瀏覽器沒有對不可見狀態(tài)時的setInterval進行性能優(yōu)化,不可見前后間隔時間不變

setTimeout

接下來是setTimeout

function timer() {
  setTimeout(function() {
    const myDate = new Date();
    const currentDate = myDate.getMinutes() + '分'+ myDate.getSeconds() + '秒' + myDate.getMilliseconds() + '豪秒';
    console.log(currentDate);
    timer();
  }, 500)
}
// 兼容ie寫法
document.getElementById('btn').addEventListener('click', function() {
  timer();
});

同樣先來看看在谷歌瀏覽器中的表現(xiàn)(還是500ms和2s)

我們發(fā)現(xiàn)在谷歌瀏覽器中,500ms的間隔,setTimeout和setInterval表現(xiàn)一致,都是最小間隔限制為1s。但是2s隔間的測試結(jié)果出現(xiàn)了分歧,頁面不可見之后,間隔變成了3s。繼續(xù)經(jīng)過多次的測試,如下,左圖的間隔時間為990ms,右圖的間隔時間為1s。

不可見狀態(tài)下,左圖中的990ms間隔時間變?yōu)?s,右圖中的1s間隔時間變?yōu)?s。

我們再來看看火狐(500ms和2s)

火狐瀏覽器不可見狀態(tài)下,左圖中的500ms變?yōu)?s,右圖中的2s保持不變。

再來看看ie瀏覽器(500ms)

一樣毫無優(yōu)化。

我們可以得出結(jié)論

  • 在谷歌瀏覽器中,setTimeout在瀏覽器不可見狀態(tài)下間隔低于1s的會變?yōu)?s,大于等于1s的會變成N+1s的間隔值。
  • 火狐瀏覽器下setTimeout的最小間隔時間會變?yōu)?s,大于等于1s的間隔不變。ie瀏覽器在不可見狀態(tài)前后的間隔時間不變。

requestAnimationFrame

raf是瀏覽器提供的一個更流暢的處理動畫的方法,它會在下次瀏覽器GUI繪制頁面的時候運行傳入的方法。GUI繪制頁面的頻率跟顯示器的刷新率有關,普通顯示器的刷新率是60hz,因此raf在一秒之內(nèi)需要運行60次,間隔四舍五入大概是17ms。

function timer() {
  const myDate = new Date();
  const currentDate = myDate.getMinutes() + '分'+ myDate.getSeconds() + '秒' + myDate.getMilliseconds() + '豪秒';
  console.log(currentDate);
  window.requestAnimationFrame(timer)
}
// 兼容ie寫法
document.getElementById('btn').addEventListener('click', function() {
  timer();
});

我們來看看不同瀏覽器下面的表現(xiàn):

谷歌瀏覽器

火狐瀏覽器

ie瀏覽器

我們可以發(fā)現(xiàn),谷歌瀏覽器和ie瀏覽器當瀏覽器狀態(tài)為不可見時,raf方法將停止執(zhí)行?;鸷鼮g覽器當狀態(tài)變?yōu)椴豢梢姇r,會在間隔是1s,2s,4s,8s,16s,32s...這樣的順序下去執(zhí)行raf方法。

總結(jié)

谷歌瀏覽器中,當頁面處于不可見狀態(tài)時,setInterval的最小間隔時間會被限制為1s?;鸷鼮g覽器的setInterval和谷歌特性一致。ie瀏覽器沒有對不可見狀態(tài)時的setInterval進行性能優(yōu)化,不可見前后間隔時間不變。

在谷歌瀏覽器中,setTimeout在瀏覽器不可見狀態(tài)下間隔低于1s的會變?yōu)?s,大于等于1s的會變成N+1s的間隔值。火狐瀏覽器下setTimeout的最小間隔時間會變?yōu)?s,大于等于1s的間隔不變。ie瀏覽器在不可見狀態(tài)前后的間隔時間不變。

谷歌瀏覽器和ie瀏覽器當瀏覽器狀態(tài)為不可見時,raf方法將停止執(zhí)行?;鸷鼮g覽器當狀態(tài)變?yōu)椴豢梢姇r,會在間隔是1s,2s,4s,8s,16s,32s...這樣的順序下去執(zhí)行raf方法。

如何解決

碰到問題當然需要解決,在一些定時器小于1s的倒計時的頁面中,如果用戶切換到了其他標簽頁。再切回去的時候,頁面上顯示的倒計時時間其實是錯誤的,這種隱藏的bug會帶來很大的風險。該怎么解決呢?

除了調(diào)取后臺接口或者websocket連接之外,其實有一個更好的解決方案,webWorkers。而且webWorkers還可以解決一個頁面存在多個定時器時候間隔時間誤差較大的問題。

直接上例子

document.getElementById('btn').addEventListener('click', function() {
  var w = new Worker('demo_workers.js');
  w.onmessage = function(event){
    console.log(event.data);
  };
});
//瀏覽器切換事件
document.addEventListener('visibilitychange', function() { 
  if(document.hidden) {
    console.log('頁面不可見');
  }
});
// demo_workers.js
setInterval(function() {
  const myDate = new Date();
  const currentDate = myDate.getMinutes() + '分'+ myDate.getSeconds() + '秒' + myDate.getMilliseconds() + '豪秒';
  postMessage(currentDate);
}, 500);

實際結(jié)果

間隔保持一致。

以上就是瀏覽器切換到其他標簽頁或最小化js定時器是否準時測試的詳細內(nèi)容,更多關于瀏覽器切換js定時器準時測試的資料請關注腳本之家其它相關文章!

相關文章

  • lodash內(nèi)部方法getFuncName及setToString剖析詳解

    lodash內(nèi)部方法getFuncName及setToString剖析詳解

    本篇章我們主要是通過了解lodash里的兩個內(nèi)部方法getFuncName方法和setToString方法,在實際開發(fā)中我們也可以借鑒方法的實現(xiàn)思路,在需要的時候簡單封裝一下,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-09-09
  • JS?class語法糖的深入剖析

    JS?class語法糖的深入剖析

    這篇文章主要為大家介紹了JS?class語法糖的深入剖析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-07-07
  • 微信小程序 數(shù)據(jù)交互與渲染實例詳解

    微信小程序 數(shù)據(jù)交互與渲染實例詳解

    這篇文章主要介紹了微信小程序 數(shù)據(jù)交互與渲染實例詳解的相關資料,需要的朋友可以參考下
    2017-01-01
  • 前端利用jsencrypt.js進行RSA加密示例詳解

    前端利用jsencrypt.js進行RSA加密示例詳解

    這篇文章主要為大家介紹了前端利用jsencrypt.js進行RSA加密示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-08-08
  • 瀏覽器切換到其他標簽頁或最小化js定時器是否準時測試

    瀏覽器切換到其他標簽頁或最小化js定時器是否準時測試

    這篇文章主要為大家介紹了瀏覽器切換到其他標簽頁或最小化是js定時器是否準時的測試詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-07-07
  • 前端取消請求及取消重復請求方式

    前端取消請求及取消重復請求方式

    這篇文章主要為大家介紹了前端取消請求及取消重復請求方式,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-07-07
  • 創(chuàng)建圖片對比slider滑塊示例詳解

    創(chuàng)建圖片對比slider滑塊示例詳解

    這篇文章主要為大家介紹了創(chuàng)建圖片對比slider滑塊示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-08-08
  • js中yield參數(shù)應用示例深入理解

    js中yield參數(shù)應用示例深入理解

    這篇文章主要為大家介紹了js中yield參數(shù)應用示例深入理解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-08-08
  • Astro Islands靜態(tài)頁面交互式UI組件

    Astro Islands靜態(tài)頁面交互式UI組件

    這篇文章主要為大家介紹了Astro Islands靜態(tài)頁面交互式UI組件使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-08-08
  • ECMAScript?modules規(guī)范示例詳解

    ECMAScript?modules規(guī)范示例詳解

    這篇文章主要為大家介紹了ECMAScript?modules規(guī)范示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-11-11

最新評論