更快的异步执行(setTimeout多浏览器)


Posted in Javascript onAugust 12, 2014

如果要异步执行一个函数,我们最先想到的方法肯定会是setTimeout
例如:setTimeout(function( /* 1s后做点什么 */){},1000}

那如果说要最快速地异步执行一个函数呢?
是否会是:

setTimeout(function( /* 尽快做点什么 */){},0}

可惜的是,浏览器为了避免setTimeout嵌套可能出现卡死ui线程的情况,为setTimeout设置了最小的执行时间间隔,不同浏览器的最小执行时间间隔都不一样。chrome下测试 setTimeout 0 的实际执行时间间隔大概在12ms左右。

那么如果想最快地异步执行一个函数,有没有什么可以提速的方法呢?

先来看看浏览器端,有哪些常用的异步执行方法

setImmediate:该方法去实现比setTimeout 0 更快的异步执行,执行时间更接近0ms,但是只有IE/node支持。

requestAnimationFrame:做动画循环的时候经常会用到这个方法,该方法只会在浏览器刷新ui的时候执行,刷新ui的频率最大一般为60fps,所以requestAnimationFrame一般情况下比setTimeout 0 更慢一些。

除了使用异步函数外,还有一些方法可以实现异步调用

利用onmessage:
和iframe通信时常常会使用到onmessage方法,但是如果同一个window postMessage给自身,会怎样呢?其实也相当于异步执行了一个function
例如:

var doSth = function(){}
window.addEventListener("message", doSth, true);
window.postMessage("", "*");


另外,还可以利用script标签,实现函数异步执行,例如:

var newScript = document.createElement("script");
newScript.onreadystatechange = doSth;
document.documentElement.appendChild(newScript);



把script添加到文档也会执行onreadystatechange 但是该方法只能在IE下浏览器里使用。

那么 这几种方法,谁最快?

测试了一下,

chrome下:

setImmediate:不可用。
setTimeout 0:12ms
onmessage:6ms
onreadystatechange:不支持

chrome下,onmessage比setTimeout 0 更快。

firefox下:

setImmediate:不可用。
setTimeout 0:7ms
onmessage:7ms
onreadystatechange:不支持

firefox下,onmessage和setTimeout 0 速度相当。

IE9:

setImmediate:不可用。
setTimeout 0:11ms
onmessage:7ms 10ms
onreadystatechange:2ms

IE9下,onreadystatechange的时间比另外两者要快得多。

总体情况下,setImmediate < readystatechange < onmessage < setTimeout 0 < requestAnimationFrame
因此我们可以简单封装一个快速执行异步function的方法:

var setZeroTimeout = (function(){
if(window.setImmediate){
//IE10+版本,使用原生setImmediate
return window.setImmediate;
}
else if("onreadystatechange" in document.createElement("script")){
return function(){/* 使用onreadystatechange的版本 */}
}
else if(window.postMessage){
return function(){/* 使用onmessage的异步执行版本 */}
}
else {
return window.setTimeout;
}

})();
Javascript 相关文章推荐
JQuery之focus函数使用介绍
Aug 20 Javascript
输入框过滤非数字的js代码
Sep 18 Javascript
整理AngularJS框架使用过程当中的一些性能优化要点
Mar 05 Javascript
基于Jquery插件实现跨域异步上传文件功能
Apr 26 Javascript
JS对HTML表格进行增删改操作
Aug 22 Javascript
微信小程序 获取javascript 里的数据
Aug 17 Javascript
Vue.js用法详解
Nov 13 Javascript
JavaScript设计模式之享元模式实例详解
Jan 17 Javascript
vue使用Font Awesome的方法步骤
Feb 26 Javascript
JavaScript实现更换背景图片
Oct 18 Javascript
谈一谈vue请求数据放在created好还是mounted里好
Jul 27 Javascript
浅谈react路由传参的几种方式
Mar 23 Javascript
JavaScript Promise启示录
Aug 12 #Javascript
深入理解Javascript中this的作用域
Aug 12 #Javascript
javascript实现在某个元素上阻止鼠标右键事件的方法和实例
Aug 12 #Javascript
JavaScript弹出窗口方法汇总
Aug 12 #Javascript
Javascript中3种实现继承的方法和代码实例
Aug 12 #Javascript
jQuery判断checkbox是否选中的3种方法
Aug 12 #Javascript
jquery判断浏览器后退时候弹出消息的方法
Aug 11 #Javascript
You might like
关于拼配咖啡,你要知道
2021/03/03 咖啡文化
4.与数据库的连接
2006/10/09 PHP
PHP中的类-什么叫类
2006/11/20 PHP
php中判断一个字符串包含另一个字符串的方法
2007/03/19 PHP
PHP中数组的三种排序方法分享
2012/05/07 PHP
基于PHP magic_quotes_gpc的使用方法详解
2013/06/24 PHP
采用CSS和JS,刚好我最近有个站点要用到下拉菜单!
2006/06/26 Javascript
用jscript实现新建word文档
2007/06/15 Javascript
javascript import css实例代码
2008/07/18 Javascript
javascript textarea光标定位方法(兼容IE和FF)
2011/03/12 Javascript
浅析JavaScript中两种类型的全局对象/函数
2013/12/05 Javascript
JS下载文件|无刷新下载文件示例代码
2014/04/17 Javascript
jquery鼠标放上去显示悬浮层即弹出定位的div层
2014/04/25 Javascript
jquery实现的Accordion折叠面板效果代码
2015/09/02 Javascript
JS组件Form表单验证神器BootstrapValidator
2016/01/26 Javascript
浅谈时钟的生成(js手写简洁代码)
2016/08/20 Javascript
JS实现的样式切换功能tableCSS实例
2016/12/30 Javascript
Bootstrap table表格简单操作
2017/02/07 Javascript
js模拟实现烟花特效
2020/03/10 Javascript
Java 生成随机字符的示例代码
2021/01/13 Javascript
[51:29]Alliance vs TNC 2019国际邀请赛小组赛 BO2 第二场 8.16
2019/08/18 DOTA
Python列表切片用法示例
2017/04/19 Python
Python 利用scrapy爬虫通过短短50行代码下载整站短视频
2018/10/29 Python
Python Web版语音合成实例详解
2019/07/16 Python
HTML5调用手机发短信和打电话功能
2020/04/29 HTML / CSS
新秀丽官方旗舰店:Samsonite拉杆箱、双肩包、皮具
2018/03/05 全球购物
Shop Apotheke瑞士:您的健康与美容网上商店
2019/10/09 全球购物
手工制作的意大利皮革运动鞋:KOIO
2020/01/05 全球购物
网吧收银员岗位职责
2013/12/14 职场文书
初中优秀教师事迹材料
2014/08/18 职场文书
党的作风建设心得体会
2014/10/22 职场文书
大学生求职意向书
2015/05/11 职场文书
2015年高三班主任工作总结
2015/05/21 职场文书
python异常中else的实例用法
2021/06/15 Python
mybatis3中@SelectProvider传递参数方式
2021/08/04 Java/Android
Python Django / Flask如何使用Elasticsearch
2022/04/19 Python