使用JS實(shí)現(xiàn)一個高精準(zhǔn)定時器和延時器
一、為什么瀏覽器定時器不精準(zhǔn)?
1?? JS 是單線程
- 主線程被占用 → 定時器回調(diào)延遲
- UI / 渲染 / GC 都會阻塞
2?? 瀏覽器最小時間精度限制
- HTML5 規(guī)范限制(4ms)
- 后臺 Tab 被強(qiáng)制降頻(1000ms+)
3?? setInterval 的“時間漂移”
setInterval(fn, 1000); // 實(shí)際執(zhí)行時間 = 1000 + fn執(zhí)行時間
時間會越來越不準(zhǔn)
二、高精準(zhǔn)定時器的核心思想(先記?。?/h2>
不用“執(zhí)行次數(shù)”計時,而用“時間戳”對齊真實(shí)時間。
不用“執(zhí)行次數(shù)”計時,而用“時間戳”對齊真實(shí)時間。
三、高精準(zhǔn)延時器(setTimeout 替代方案)
實(shí)現(xiàn):時間戳校正 法
function preciseTimeout(fn, delay) {
const start = performance.now();
function loop() {
const now = performance.now();
if (now - start >= delay) {
fn();
} else {
requestAnimationFrame(loop);
}
}
loop();
}
為什么準(zhǔn)?
- 使用高精度時鐘
performance.now() - 每幀校正誤差
四、高精準(zhǔn)定時器(setInterval 替代方案)
實(shí)現(xiàn):遞歸 setTimeout + 時間修正
function preciseInterval(fn, interval) {
let expected = performance.now() + interval;
function step() {
const drift = performance.now() - expected;
fn();
expected += interval;
setTimeout(step, Math.max(0, interval - drift));
}
setTimeout(step, interval);
}
核心點(diǎn)
- 不是簡單等待 interval
- 每次都修正漂移
五、Web Worker 定時器(更準(zhǔn))
為什么 Worker 更準(zhǔn)?
- 不阻塞 UI 線程
- 不受頁面渲染影響
worker.js
setInterval(() => {
postMessage(Date.now());
}, 1000);
主線程
const worker = new Worker('worker.js');
worker.onmessage = () => {
console.log('tick');
};
計時類、音頻、監(jiān)控系統(tǒng)首選
六、requestAnimationFrame 方案(適合動畫)
let last = performance.now();
function rafTimer() {
const now = performance.now();
if (now - last >= 1000) {
console.log('tick');
last = now;
}
requestAnimationFrame(rafTimer);
}
rafTimer();
七、三種方案對比(面試必背)
| 方案 | 精度 | 適合場景 |
|---|---|---|
| setTimeout | 低 | 普通任務(wù) |
| 時間校正 | 高 | 業(yè)務(wù)定時 |
| Web Worker | 很高 | 長期計時 |
| RAF | 高 | 動畫 / UI |
八、延時器 vs 定時器(概念區(qū)分)
| 類型 | 特點(diǎn) |
|---|---|
| 延時器 | 執(zhí)行一次 |
| 定時器 | 周期執(zhí)行 |
| 高精準(zhǔn) | 基于時間差 |
九、后臺 / 鎖屏問題(高級)
問題
- 瀏覽器后臺 Tab 會降頻
解決方案
- Web Worker
- Visibility API + 校正
- 服務(wù)端時間對齊
十、30 秒面試標(biāo)準(zhǔn)回答(直接背)
瀏覽器原生定時器會因主線程阻塞產(chǎn)生時間漂移;
高精準(zhǔn)定時器應(yīng)基于時間戳校正,而不是固定間隔;
可以通過遞歸 setTimeout、requestAnimationFrame 或 Web Worker 提升精度;
對精度要求極高的場景應(yīng)使用 Worker 或服務(wù)端時間同步。
以上就是使用JS實(shí)現(xiàn)一個高精準(zhǔn)定時器和延時器的詳細(xì)內(nèi)容,更多關(guān)于JS實(shí)現(xiàn)定時器和延時器的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
學(xué)習(xí)JSON.stringify的9大特性和轉(zhuǎn)換規(guī)則
本文介紹JSON.stringify9大特性和轉(zhuǎn)換規(guī)則,JSON.stringify()方法將一個JavaScript對象或值轉(zhuǎn)換為?JSON?字符串,如果指定了一個replacer?函數(shù),則可以選擇性地替換值,或者指定的replacer是數(shù)組,則可選擇性地僅包含數(shù)組指定的屬性,更多內(nèi)容需要的小火煸可以參考下面溫行內(nèi)容2022-02-02
Promise.race和Promise.any使用示例詳解
這篇文章主要為大家介紹了如何使用Promise.race() 和 Promise.any() 示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-11-11
javascript字符串與數(shù)組轉(zhuǎn)換匯總
本文給大家分享的是Js中字符串轉(zhuǎn)換成數(shù)組,數(shù)組轉(zhuǎn)換成字符串的函數(shù),十分的簡單實(shí)用,有需要的小伙伴可以參考下。2015-05-05
javascript模擬實(shí)現(xiàn)C# String.format函數(shù)功能代碼
這篇文章主要介紹了javascript模擬實(shí)現(xiàn)C# String.format函數(shù)功能,相信大家可以用的到2013-11-11
js中substring和substr兩者區(qū)別和使用方法
這篇文章主要介紹了js中substring和substr兩者區(qū)別和使用方法,每一個步驟都有相應(yīng)的文字介紹,感興趣的小伙伴們可以參考一下2015-11-11
js,jq,css多方面實(shí)現(xiàn)簡易下拉菜單功能
這篇文章主要介紹了js,jq,css多方面實(shí)現(xiàn)簡易下拉菜單功能,需要的朋友可以參考下2017-05-05

