js定时器优化
在js中如果打算使用setInterval进行倒数,计时等功能,往往是不准确的,因为setInterval的回调函数并不是到时后立即执行,而是等系统计算资源空闲下来后才会执行.而下一次触发时间则是在setInterval回调函数执行完毕之后才开始计时,所以如果setInterval内执行的计算过于耗时,或者有其他耗时任务在执行,setInterval的计时会越来越不准,延迟很厉害.
先看以下两看计时器
setTimeout版
function test(){
count += 1;
console.log(`第${count}次开始 ${getTime.now() - startTime} ID:${t}`); // 显示开始时间 console.log(`第${count}次结束 ${getTime.now() - startTime}`); // 显示结束时间 //count<1000 && setTimeout(test,500); //这样写没有ID
if(count<1000) t=setTimeout(test,500); //这样写没有ID
} let count = -1;
let getTime = window.performance;
let startTime = getTime.now();
var t; test(); // 300ms间隔
运行结果
误差很大,原因js是单线程,而setTimeout两次时间间隔为timer执行时间+interval延时时间,久而久之积累的误差就大了
setInterval版
function sleep(time) {
let startTime = window.performance.now();
while (window.performance.now() - startTime < time) {}
} function test(){
count++;
console.log(`第${count}次开始 ${getTime.now() - startTime}`);
// 显示开始时间
//sleep(100); // 程序滞留500ms
console.log(`第${count}次结束 ${getTime.now() - startTime}`); // 显示结束时间
count>1000 && clearInterval(t);
} let count = 0;
let getTime = window.performance;
let startTime = getTime.now(); var t = setInterval(test , 500); // 300ms间隔
最后结果:
测了两次结果差很多,可能应该是第一次我切出当前页的原因,已至getTime.now();出错,从第二个结果看,还是很精准的,但是,
第一种写法:
1
2
3
4
|
funciton xxx(){ //函数代码,此处执行时间约20毫秒 setTimeout(xxx,10) } |
第二种写法:
1
2
3
4
|
funciton xxx(){ //函数代码,此处执行时间约20毫秒 } setInterval(xxx,10) |
第一种写法中,只有执行完20ms的代码后,再等10ms才会开始下一个循环;
第二种写法中,无论有没有执行完20ms的代码,10ms后都会开始下一个循环
setTimeout优化版:
var startTime0 = new Date().getTime();
let count = 0;
let getTime = window.performance;
let startTime = getTime.now();
var t;
//setTimeout(test,500); // 300ms间隔 setTimeout(function () {
count += 1;
console.log(`第${count}次开始 ${getTime.now() - startTime}`);
// 显示开始时间
//sleep(500); // 程序滞留500ms var offset = getTime.now() - (startTime + count * 500);
var nextTime = 500 - offset;
//console.log(nextTime);
if (nextTime < 0) nextTime = 0;
console.log(`第${count}次结束 ${getTime.now() - startTime} 下次延时:${nextTime}`); // 显示结束时间
if(count<1000){setTimeout(arguments.callee, nextTime);} }, 500)
setTimeout优化后的结果
setTimeout优化说明:
1、最大的特点就是动态修正当前触发的延迟时间。
2、为什么选择setTimeout,因为setTimeout更方便调节延迟时间。
3、使用performance.now()是当前时间与performance.timing.navigationStart的时间差,以微秒(百万分之一秒)为单位的时间,与 Date.now()-performance.timing.navigationStart的区别是不受系统程序执行阻塞的影响,因此更加精准。关于performance的更多内容
4、第二个setTimeout()调用使用了agrument.callee 来获取当前实行函数的引用,并设置另外一个新定时器。这样做可以保证在代码执行完成前不会有新的定时器插入。(来自)
相关链接:https://blog.csdn.net/acm765152844/article/details/51298915
js定时器优化的更多相关文章
- javascript定时器,取消定时器,及js定时器优化方法
通常用的方法: 启动定时器: window.setInterval(Method,Time) Method是定时调用的js方法 Time是间隔时间,单位是毫秒 取消定时器: clearInterval ...
- JS定时器不可靠的原因及解决方案
前言 在工作中应用定时器的场景非常多,但你会发现有时候定时器好像并没有按照我们的预期去执行,比如我们常遇到的setTimeout(()=>{},0)它有时候并不是按我们预期的立马就执行.想要知道 ...
- 应用r.js来优化你的前端
r.js是requireJS的优化(Optimizer)工具,可以实现前端文件的压缩与合并,在requireJS异步按需加载的基础上进一步提供前端优化,减小前端文件大小.减少对服务器的文件请求.要使用 ...
- js性能优化-事件委托
js性能优化-事件委托 考虑一个列表,在li的数量非常少的时候,为每一个li添加事件侦听当然不会存在太多性能方面的问题,但是当列表非常的长,长到上百上千甚至上万的时候(当然只是一个解释,实际工作中很少 ...
- js定时器的使用(实例讲解)
在javascritp中,有两个关于定时器的专用函数,分别为: 1.倒计定时器:timename=setTimeout("function();",delaytime);2.循环定 ...
- 移动Web与js定时器暂停或不准确计时的问题解决
PC 上的 Firefox.Chrome 和 Safari 等浏览器,都会自动把未激活页面中的 JavaScript 定时器(setTimeout.setInterval)间隔最小值改为 1 秒以上: ...
- js定时器 特定时间执行某段程序的例子
定时器想必大家并不陌生吧,在本文为大家详细介绍下js中是如何实现定时器的,具体原理及代码如下. 例子: $(function(){ var handler = function(){ //www.jb ...
- js定时器setInterval()与setTimeout()
js定时器setInterval()与setTimeout() 1.setTimeout(Expression,DelayTime),在DelayTime过后,将执行一次Expression,setT ...
- js 性能优化利器:prepack
1. js 性能优化 js 本身是没有像 python 一样的预编译功能,更没有像 java 一样的编译功能,所以,这里所说的 js 代码预编译 只是通过工具实现的类似功能而已. 这就要提到 prep ...
随机推荐
- 013-并发编程-java.util.concurrent.locks之-AbstractQueuedSynchronizer-用于构建锁和同步容器的框架、独占锁与共享锁的获取与释放
一.概述 AbstractQueuedSynchronizer (简称AQS),位于java.util.concurrent.locks.AbstractQueuedSynchronizer包下, A ...
- Cglib动态代理实现原理
Cglib动态代理实现方式 我们先通过一个demo看一下Cglib是如何实现动态代理的. 首先定义个服务类,有两个方法并且其中一个方法用final来修饰. public class PersonSer ...
- C++中为何大量使用类指针
C++的精髓之一就是多态性,只有指针或者引用可以达到多态.对象不行类指针的优点: 第一实现多态. 第二,在函数调用,传指针参数.不管你的对象或结构参数多么庞大,你用指针,传过去的就是4个字节.如果用对 ...
- 多线程——interrupt方法
测试interrupt()方法: package day_12_01_Thread; import java.util.Date; /** * 测试interrupt()方法:结束线程,但是线程还是活 ...
- PHP数组和字符串的处理函数汇总
大部分数组处理函数array_chunk — 将一个数组分割成多个array_column — 返回数组中指定的一列array_combine — 创建一个数组,用一个数组的值作为其键名,另一个数组的 ...
- DS1-3
#include <stdio.h> #include <string.h> #define MAXSIZE 1024 double polynomial[MAXSIZE]; ...
- Spring MVC定时服务
spring-mvc-config.xml <context:component-scan base-package="com.bf" ></context:co ...
- nginx反向代理 支持WebSocket
WebSocket(简称WS)协议的握手和HTTP是兼容的,通过HTTP/1.1中协议转换机制,客户端可以传递名为“Upgrade” 头部信息将连接从HTTP连接升级到WebSocket连接 那么反向 ...
- Centos7搭建Postfix发送邮件 Connection timed out
telent mx1.qq.com 25 25这个端口是不加密的,不安全,qq邮箱和网易的邮箱早就不用了.采用加密的方式
- HTTPS安全不?
首先,它是什么?我的理解是一开始进行SSL握手,商量好将要使用哪些加密算法来通讯,或者加密方法后使用非对称的加密方法,交互一下随机数,加上一个pre-master-secrect的,然后服务端利用私钥 ...