成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

當(dāng)瀏覽器切換到其他標(biāo)簽頁(yè)或最小化js定時(shí)器是否會(huì)影響準(zhǔn)時(shí)

3403771864 / 1146人閱讀

  前言

  很多的問題就在實(shí)踐中得到解決。

  本文主要說的就是js定時(shí)器,setInterval和setTimeout,作為我們?nèi)粘i_發(fā)經(jīng)常使用到的方法。我們先給大家下面一個(gè)例子:

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

  這段代碼就是每過500ms打印一次1(實(shí)際運(yùn)行還需要考慮js的宏任務(wù)和微任務(wù)的執(zhí)行時(shí)間,定時(shí)器的間隔時(shí)間是500ms,但是定時(shí)器中的方法觸發(fā)可能需要在宏任務(wù)隊(duì)列中排隊(duì),不一定會(huì)在500ms的時(shí)候觸發(fā),關(guān)于Event Loop的基礎(chǔ)內(nèi)容不在本文討論之內(nèi))。

  但要是從當(dāng)前頁(yè)面切換到另一個(gè)標(biāo)簽頁(yè),或者把瀏覽器最小化了,這時(shí)候,這個(gè)頁(yè)面定時(shí)器的間隔時(shí)間還是500ms?

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

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

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

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

  document.visibilityState有三個(gè)值

  hidden:頁(yè)面徹底不可見。

  visible:頁(yè)面至少一部分可見。

  prerender:頁(yè)面即將或正在渲染,處于不可見狀態(tài)。要知道重點(diǎn)關(guān)注hidden,主要就是它可以在瀏覽器切換當(dāng)前頁(yè)面到另外一個(gè)標(biāo)簽頁(yè)或者把瀏覽器最小化的時(shí)候,document.visibilityState就會(huì)是hidden值。由此可以使用document.hidden,它返回一個(gè)布爾值,為true的時(shí)候,說明當(dāng)前瀏覽器是不可見狀態(tài)。

  setInterval

  我們先來測(cè)試setInterval,代碼如下

 

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

  定時(shí)器間隔是500ms,谷歌瀏覽器如下

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

  前后間隔時(shí)間一致。

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

  ie瀏覽器

  在不斷的測(cè)試中,谷歌瀏覽器中,當(dāng)頁(yè)面處于不可見狀態(tài)時(shí),setInterval的最小間隔時(shí)間會(huì)被限制為1s?;鸷鼮g覽器的setInterval和谷歌特性一致,但是ie瀏覽器沒有對(duì)不可見狀態(tài)時(shí)的setInterval進(jìn)行性能優(yōu)化,不可見前后間隔時(shí)間不變。

  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)

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

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

  我們?cè)賮砜纯椿鸷?00ms和2s)

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

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

  顯而易見并無改動(dòng)?! ?/p>

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

  火狐瀏覽器下setTimeout的最小間隔時(shí)間會(huì)變?yōu)?s,大于等于1s的間隔不變。ie瀏覽器在不可見狀態(tài)前后的間隔時(shí)間不變。

  requestAnimationFrame

  raf是瀏覽器提供的一個(gè)更流暢的處理動(dòng)畫的方法,它會(huì)在下次瀏覽器GUI繪制頁(yè)面的時(shí)候運(yùn)行傳入的方法。GUI繪制頁(yè)面的頻率跟顯示器的刷新率有關(guān),普通顯示器的刷新率是60hz,因此raf在一秒之內(nèi)需要運(yùn)行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瀏覽器當(dāng)瀏覽器狀態(tài)為不可見時(shí),raf方法將停止執(zhí)行?;鸷鼮g覽器當(dāng)狀態(tài)變?yōu)椴豢梢姇r(shí),會(huì)在間隔是1s,2s,4s,8s,16s,32s...這樣的順序下去執(zhí)行raf方法。

  匯總

  當(dāng)頁(yè)面處于不可見狀態(tài)時(shí),谷歌瀏覽器中,當(dāng)頁(yè)面處于不可見狀態(tài)時(shí),setInterval的最小間隔時(shí)間會(huì)被限制為1s。火狐瀏覽器的setInterval和谷歌特性一致。ie瀏覽器沒有對(duì)不可見狀態(tài)時(shí)的setInterval進(jìn)行性能優(yōu)化,不可見前后間隔時(shí)間不變。

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

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

  解決方法

  在一些定時(shí)器小于1s的倒計(jì)時(shí)的頁(yè)面中,如果用戶切換到了其他標(biāo)簽頁(yè)。再切回去的時(shí)候,頁(yè)面上顯示的倒計(jì)時(shí)時(shí)間其實(shí)是錯(cuò)誤的,這可是一個(gè)大的bug,要如何解決?

  我們處理可以調(diào)取后臺(tái)接口或者websocket連接之外,還有一個(gè)更好的方法:webWorkers。而且webWorkers還可以解決一個(gè)頁(yè)面存在多個(gè)定時(shí)器時(shí)候間隔時(shí)間誤差較大的問題。

  直接上例子

  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('頁(yè)面不可見');
  }
  });


 // demo_workers.js
  setInterval(function() {
  const myDate = new Date();
  const currentDate = myDate.getMinutes() + '分'+ myDate.getSeconds() + '秒' + myDate.getMilliseconds() + '豪秒';
  postMessage(currentDate);
  }, 500);

  實(shí)際結(jié)果

  間隔保持一致。

    很多問題看似在“吹毛求疵”,但何嘗不是一種進(jìn)步。


文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/128192.html

相關(guān)文章

  • 覽器知識(shí)

    摘要:瀏覽器的渲染進(jìn)程是多線程的。異步請(qǐng)求線程在在連接后是通過瀏覽器新開一個(gè)線程請(qǐng)求將檢測(cè)到狀態(tài)變更時(shí),如果設(shè)置有回調(diào)函數(shù),異步線程就產(chǎn)生狀態(tài)變更事件,將這個(gè)回調(diào)再放入事件隊(duì)列中。 [TOC] 瀏覽器進(jìn)程線程 區(qū)分線程和進(jìn)程 **- 什么是進(jìn)程** 狹義定義:進(jìn)程是正在運(yùn)行的程序的實(shí)例(an instance of a computer program that is being exe...

    Pluser 評(píng)論0 收藏0
  • 演示當(dāng)時(shí)器在頁(yè)面小化時(shí)無法執(zhí)行

      我們講述的是關(guān)于 ahooks 源碼系列文章的第七篇,總結(jié)主要講述下面幾點(diǎn):  鞏固 React hooks 的理解?! W(xué)習(xí)如何抽象自定義 hooks。構(gòu)建屬于自己的 React hooks 工具庫(kù)?! ∨囵B(yǎng)閱讀學(xué)習(xí)源碼的習(xí)慣,工具庫(kù)是一個(gè)對(duì)源碼閱讀不錯(cuò)的選擇?! ∽ⅲ罕鞠盗袑?duì) ahooks 的源碼解析是基于v3.3.13。自己 folk 了一份源碼,主要是對(duì)源碼做了一些解讀,可見詳情?! ?..

    3403771864 評(píng)論0 收藏0
  • js基礎(chǔ)--如何判斷覽器標(biāo)簽頁(yè)是隱藏或者顯示狀態(tài)

    摘要:歡迎訪問我的個(gè)人博客前言在工作中我們可能會(huì)遇到這樣的需求,當(dāng)瀏覽器切換到別的標(biāo)簽頁(yè)或著最小化時(shí),我們需要暫停頁(yè)面上正在播放的視頻或者音樂,這個(gè)需求就會(huì)用到我下面要說的這個(gè)知識(shí)點(diǎn)具體用法瀏覽器標(biāo)簽頁(yè)隱藏或者顯示時(shí)會(huì)改變和的值,我們可以通過這個(gè) 歡迎訪問我的個(gè)人博客:http://www.xiaolongwu.cn 前言 在工作中我們可能會(huì)遇到這樣的需求,當(dāng)瀏覽器切換到別的標(biāo)簽頁(yè)或著最小化...

    Kosmos 評(píng)論0 收藏0
  • 覽器多進(jìn)程JS單線程,JS運(yùn)行機(jī)制最全面的一次梳理

    摘要:如果看完本文后,還對(duì)進(jìn)程線程傻傻分不清,不清楚瀏覽器多進(jìn)程瀏覽器內(nèi)核多線程單線程運(yùn)行機(jī)制的區(qū)別。因此準(zhǔn)備梳理這塊知識(shí)點(diǎn),結(jié)合已有的認(rèn)知,基于網(wǎng)上的大量參考資料,從瀏覽器多進(jìn)程到單線程,將引擎的運(yùn)行機(jī)制系統(tǒng)的梳理一遍。 前言 見解有限,如有描述不當(dāng)之處,請(qǐng)幫忙及時(shí)指出,如有錯(cuò)誤,會(huì)及時(shí)修正。 ----------超長(zhǎng)文+多圖預(yù)警,需要花費(fèi)不少時(shí)間。---------- 如果看完本文后,還...

    wanghui 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<