国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

當瀏覽器切換到其他標簽頁或最小化js定時器是否會影響準時

3403771864 / 1096人閱讀

  前言

  很多的問題就在實踐中得到解決。

  本文主要說的就是js定時器,setInterval和setTimeout,作為我們日常開發經常使用到的方法。我們先給大家下面一個例子:

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

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

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

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

  瀏覽器可見和不可見狀態

  我要知道瀏覽器的可見和不可見狀態的切換會觸發visibilitychange事件,這樣就可以通過監聽這個事件來判別瀏覽器的可見狀態。

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

  document.visibilityState有三個值

  hidden:頁面徹底不可見。

  visible:頁面至少一部分可見。

  prerender:頁面即將或正在渲染,處于不可見狀態。要知道重點關注hidden,主要就是它可以在瀏覽器切換當前頁面到另外一個標簽頁或者把瀏覽器最小化的時候,document.visibilityState就會是hidden值。由此可以使用document.hidden,它返回一個布爾值,為true的時候,說明當前瀏覽器是不可見狀態。

  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() + '豪秒';
  // 每次循環打印當前時間
  console.log(currentDate);
  }, 500);
  });
  // 瀏覽器可見狀態切換事件
  document.addEventListener('visibilitychange', function() {
  if(document.hidden) {
  console.log('頁面不可見');
  }
  });

  定時器間隔是500ms,谷歌瀏覽器如下

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

  前后間隔時間一致。

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

  ie瀏覽器

  在不斷的測試中,谷歌瀏覽器中,當頁面處于不可見狀態時,setInterval的最小間隔時間會被限制為1s。火狐瀏覽器的setInterval和谷歌特性一致,但是ie瀏覽器沒有對不可見狀態時的setInterval進行性能優化,不可見前后間隔時間不變

  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();
  });

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

  通過對比,可以知道在谷歌瀏覽器中,500ms的間隔,setTimeout和setInterval表現一致,都是最小間隔限制為1s。但是2s隔間的測試結果出現了分歧,頁面不可見之后,間隔變成了3s。繼續經過多次的測試,如下,左圖的間隔時間為990ms,右圖的間隔時間為1s。

  不可見狀態下,左圖中的990ms間隔時間變為1s,右圖中的1s間隔時間變為2s。

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

  火狐瀏覽器不可見狀態下,左圖中的500ms變為1s,右圖中的2s保持不變。

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

  顯而易見并無改動。  

  在谷歌瀏覽器中,setTimeout在瀏覽器不可見狀態下間隔低于1s的會變為1s,大于等于1s的會變成N+1s的間隔值。

  火狐瀏覽器下setTimeout的最小間隔時間會變為1s,大于等于1s的間隔不變。ie瀏覽器在不可見狀態前后的間隔時間不變。

  requestAnimationFrame

  raf是瀏覽器提供的一個更流暢的處理動畫的方法,它會在下次瀏覽器GUI繪制頁面的時候運行傳入的方法。GUI繪制頁面的頻率跟顯示器的刷新率有關,普通顯示器的刷新率是60hz,因此raf在一秒之內需要運行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();
  });

  我們來看看不同瀏覽器下面的表現:

  谷歌瀏覽器

  火狐瀏覽器

  ie瀏覽器

  我們可以發現,谷歌瀏覽器和ie瀏覽器當瀏覽器狀態為不可見時,raf方法將停止執行。火狐瀏覽器當狀態變為不可見時,會在間隔是1s,2s,4s,8s,16s,32s...這樣的順序下去執行raf方法。

  匯總

  當頁面處于不可見狀態時,谷歌瀏覽器中,當頁面處于不可見狀態時,setInterval的最小間隔時間會被限制為1s。火狐瀏覽器的setInterval和谷歌特性一致。ie瀏覽器沒有對不可見狀態時的setInterval進行性能優化,不可見前后間隔時間不變。

  在谷歌瀏覽器中,setTimeout在瀏覽器不可見狀態下間隔低于1s的會變為1s,大于等于1s的會變成N+1s的間隔值。火狐瀏覽器下setTimeout的最小間隔時間會變為1s,大于等于1s的間隔不變。ie瀏覽器在不可見狀態前后的間隔時間不變。

  谷歌瀏覽器和ie瀏覽器當瀏覽器狀態為不可見時,raf方法將停止執行。火狐瀏覽器當狀態變為不可見時,會在間隔是1s,2s,4s,8s,16s,32s...這樣的順序下去執行raf方法。

  解決方法

  在一些定時器小于1s的倒計時的頁面中,如果用戶切換到了其他標簽頁。再切回去的時候,頁面上顯示的倒計時時間其實是錯誤的,這可是一個大的bug,要如何解決?

  我們處理可以調取后臺接口或者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);

  實際結果

  間隔保持一致。

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


文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/128192.html

相關文章

  • 覽器知識

    摘要:瀏覽器的渲染進程是多線程的。異步請求線程在在連接后是通過瀏覽器新開一個線程請求將檢測到狀態變更時,如果設置有回調函數,異步線程就產生狀態變更事件,將這個回調再放入事件隊列中。 [TOC] 瀏覽器進程線程 區分線程和進程 **- 什么是進程** 狹義定義:進程是正在運行的程序的實例(an instance of a computer program that is being exe...

    Pluser 評論0 收藏0
  • 演示時器在頁面小化時無法執行

      我們講述的是關于 ahooks 源碼系列文章的第七篇,總結主要講述下面幾點:  鞏固 React hooks 的理解。  學習如何抽象自定義 hooks。構建屬于自己的 React hooks 工具庫。  培養閱讀學習源碼的習慣,工具庫是一個對源碼閱讀不錯的選擇。  注:本系列對 ahooks 的源碼解析是基于v3.3.13。自己 folk 了一份源碼,主要是對源碼做了一些解讀,可見詳情。  ...

    3403771864 評論0 收藏0
  • js基礎--如何判斷覽器標簽頁是隱藏或者顯示狀態

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

    Kosmos 評論0 收藏0
  • 覽器多進程JS單線程,JS運行機制最全面的一次梳理

    摘要:如果看完本文后,還對進程線程傻傻分不清,不清楚瀏覽器多進程瀏覽器內核多線程單線程運行機制的區別。因此準備梳理這塊知識點,結合已有的認知,基于網上的大量參考資料,從瀏覽器多進程到單線程,將引擎的運行機制系統的梳理一遍。 前言 見解有限,如有描述不當之處,請幫忙及時指出,如有錯誤,會及時修正。 ----------超長文+多圖預警,需要花費不少時間。---------- 如果看完本文后,還...

    wanghui 評論0 收藏0

發表評論

0條評論

3403771864

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<