页面切换|页面切换 定时器延迟 setInterval

最近做了一个小定时器的功能,但是在标签页切换后,定时器就会出现延迟。后面发现是在页面切换后,浏览器会自动延迟我们的定时器,以便于节约资源。 【页面切换|页面切换 定时器延迟 setInterval】例子:开启一个定时器:0.5秒数字自增

大概6秒执行了14次

页面切换|页面切换 定时器延迟 setInterval
文章图片
当前页
大概11秒执行14次

页面切换|页面切换 定时器延迟 setInterval
文章图片
切换标签页
在我们切换标签页后,我们的定时器根据浏览器不同,已经能明显感觉到延迟了,这个时候如果我们要保持定时器精度,可以用web work来跑我们的代码,通过在worker里面开启定时器,发送message给外部,外部收到message,然后再执行操作,这样我们切换页面,但是worker不受影响,定时器就可以解决延迟了
// time workervar intervalIds = {}; // 监听message 开始执行定时器或者销毁 self.onmessage = function(e){ switch(e.data.command){ case 'interval:start': // 开启定时器 var intervalId = setInterval(function(){ postMessage({ message: 'interval:tick', id: e.data.id }) },e.data.interval); postMessage({ message: 'interval:started', id: e.data.id }); intervalIds[e.data.id] = intervalId; break; case 'interval:clear': // 销毁 clearInterval(intervalIds[e.data.id]); postMessage({ message: 'interval:cleared', id: e.data.id })delete intervalIds[e.data.id]; break; } }

开启worker
var worker = new Worker('./time-worker.js'); var workerTimer = { id: 0, callbacks: {}, setInterval: function(cb, interval, context) { this.id++; var id = this.id; this.callbacks[id] = { fn: cb, context: context }; worker.postMessage({ command: 'interval:start', interval: interval, id: id }); return id; },// 监听worker 里面的定时器发送的message 然后执行回调函数 onMessage: function(e) { switch (e.data.message) { case 'interval:tick': var callback = this.callbacks[e.data.id]; if (callback && callback.fn) callback.fn.apply(callback.context); break; case 'interval:cleared': delete this.callbacks[e.data.id]; break; } },// 往worker里面发送销毁指令 clearInterval: function(id) { worker.postMessage({ command: 'interval:clear', id: id }); } }; worker.onmessage = workerTimer.onMessage.bind(workerTimer);

然后我们使用的时候,直接用worker.setInterval或者workerTimer.clearInterval就可以了
页面切换|页面切换 定时器延迟 setInterval
文章图片
使用web worker 延迟问题就解决了 如果需要加入setTimeout,也是一样的步骤
演示地址
完整代码

    推荐阅读