瀏覽器中的計時器分辨率
定時器分辨率是指時鐘更新的頻率。在他們的大部分歷史中,網絡瀏覽器使用默認的系統計時器來實現諸如 setTimeout()
之類的功能 和 setInterval()
.這意味著瀏覽器只能安排代碼運行頻率與系統計時器觸發的頻率一樣高。 Internet Explorer 還使用系統時鐘來播種 Date
中的值 對象,因此只能創建具有與計時器分辨率等效的差異的日期。
簡史
Windows 機器默認的計時器分辨率為 10-15.6 毫秒(大多數為 15.6 毫秒),這意味著使用系統計時器的瀏覽器被卡在此分辨率上。當然,10-15.6 毫秒是您擁有與當今處理器一樣快的 CPU 運行速度的生命週期。您可能不會感到驚訝,直到第 8 版的 Internet Explorer 專門使用系統計時器,因此導致 John Resig 撰寫有關計時器分辨率如何影響基準的文章 1 .在 OS X 上,瀏覽器計時器比在 Windows 上準確得多。
直到最近,Window 上的其他瀏覽器也使用系統計時器,因此都停留在 15.6 毫秒的計時器分辨率。 Firefox、Safari 和 Opera 也是如此。 Chrome 可能是第一個切換到更高分辨率計時器的 Windows 瀏覽器 2 ,他們的實驗得出了一些有趣的結果。
最初的想法是讓 Chrome 擁有亞毫秒級的計時器,但後來放棄了,取而代之的是一毫秒的計時器分辨率。他們決定使用 Windows 多媒體計時器 API,它允許您指定一個分辨率小至一毫秒的計時器,並使用它來代替系統計時器。這與 Flash 和 Quicktime 等插件使用的計時器相同。
Chrome 1.0 beta 有一個一毫秒的計時器分辨率。這看起來沒問題,但隨後團隊開始收到錯誤報告。事實證明,定時器會導致 CPU 旋轉,而當 CPU 旋轉時,由於無法進入睡眠(低功耗)模式,會消耗更多的電量。 3 這導致 Chrome 將其計時器分辨率提高到 4 毫秒。
4ms 延遲在 HTML5 中被編入計時器部分
4
,其中指出 setTimeout()
的最小分辨率 應該是 4ms。 setInterval()
的最小分辨率 指定為10ms。
今天的定時器分辨率
Internet Explorer 9、Firefox 5、Safari 5.1 和 Opera 11 都具有 4 毫秒的計時器分辨率,這是 Chrome 的領先優勢。在此之前,Firefox 4 及更早版本和 Safari 5 及更早版本的計時器分辨率為 10 毫秒(顯然,這是在 WebKit 中硬編碼的)。 iOS 5 上的移動 Safari 也有一個 4ms 的計時器分辨率。 Kindle Fire 上的 Silk 具有 10 毫秒的計時器分辨率,這可能表明它是基於舊版本的 WebKit 構建的。然而,僅僅因為今天的瀏覽器具有 4 毫秒的計時器分辨率,並不意味著您將獲得該分辨率。
大多數瀏覽器還會根據不同的條件進行某種計時器節流。其目的是在適當的時候節省電池 - 從理論上講,您要么不會注意到差異,要么會很樂意在筆記本電腦或移動設備上換取更長的電池壽命。以下是定時器分辨率發生變化的一些情況:
- 當筆記本電腦使用電池供電時,Chrome 和 Internet Explorer 9+ 會切換回系統計時器。插入後,瀏覽器會切換回 4 毫秒計時器分辨率。
- Firefox 5+、Chrome 11+ 和 Internet Explorer 10+ 將非活動標籤中的計時器分辨率更改為 1000 毫秒。 5
- 當您切換到其他應用程序時,iOS5 上的 Mobile Safari 和 Kindle Fire 上的 Silk 會完全凍結計時器。當您切換回瀏覽器時,計時器會重新啟動。
瀏覽器可能會繼續調整計時器分辨率,因為它與電池供電設備的功耗有關。 HTML5 規範為瀏覽器供應商進行此類更改留出了空間。
結論
隨著瀏覽器在過去幾年的發展,一直在進行靜默計時器分辨率的演變。計時器分辨率不是經常討論的主題之一,但如果您使用的是 setTimeout()
和 setInterval()
,對功能有更深入的了解是值得的。我們越來越接近每毫秒控制瀏覽器的程度。當有人弄清楚如何在沒有 CPU 中斷的情況下管理定時器時,我們很可能會看到定時器分辨率再次下降。在那之前,請記住 4ms,但請記住,您仍然不會總是得到那個。
更新(2011 年 12 月 15 日): 更新了關於 Date
的信息 對象。
參考
- John Resig 的 JavaScript 時間準確性
- Chrome:由 Mike Belshe 調速時鐘
- Karthik Krishnan 在英特爾® 架構上的 CPU 電源利用率
- HTML5 中的計時器
- 在非活動標籤中將 setTimeout/setInterval 限制為高於 10 毫秒的時間
- Ryan Grove 的計時器分辨率測試