更快的异步执行(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动态加载图片数据练习代码
Aug 04 Javascript
Javascript根据指定下标或对象删除数组元素
Dec 21 Javascript
JavaScript 处理Iframe自适应高度(同或不同域名下)
Mar 29 Javascript
Javascript简单实现可拖动的div
Oct 22 Javascript
一个简单的动态加载js和css的jquery代码
Sep 01 Javascript
js操作css属性实现div层展开关闭效果的方法
May 11 Javascript
jQuery解决浏览器兼容性问题案例分析
Apr 15 Javascript
fullpage.js全屏滚动插件使用实例
Sep 06 Javascript
Bootstrap企业网站实战项目4
Oct 14 Javascript
微信小程序-获得用户输入内容
Feb 13 Javascript
JS实现利用两个队列表示一个栈的方法
Dec 13 Javascript
微信小程序实现modal弹出框遮罩层组件(可带文本框)
Dec 20 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
967 个函式
2006/10/09 PHP
php 编写安全的代码时容易犯的错误小结
2010/05/20 PHP
批量修改RAR文件注释的php代码
2010/11/20 PHP
有关phpmailer的详细介绍及使用方法
2013/01/28 PHP
php页面消耗内存过大的处理办法
2013/03/18 PHP
浅谈PHP中的数据传输CURL
2016/09/06 PHP
windows下的WAMP环境搭建图文教程(推荐)
2017/07/27 PHP
PHP7匿名类的用法示例
2019/04/05 PHP
Avengerls vs KG BO3 第一场2.18
2021/03/10 DOTA
编写Js代码要注意的几条规则
2010/09/10 Javascript
非常强大的 jQuery.AsyncBox 弹出对话框插件
2011/08/29 Javascript
jquery 添加节点的几种方法介绍
2013/09/04 Javascript
Javascript显示和隐藏ul列表的方法
2015/07/15 Javascript
JavaScript使用DeviceOne开发实战(四)仿优酷视频应用
2015/12/02 Javascript
AngularJS在IE8的不支持的解决方法
2016/05/13 Javascript
Vue.js第四天学习笔记(组件)
2016/12/02 Javascript
深入理解jquery中的each用法
2016/12/14 Javascript
微信小程序自定义组件
2017/08/16 Javascript
深入理解requireJS-实现一个简单的模块加载器
2018/01/15 Javascript
vue-cli脚手架-bulid下的配置文件
2018/03/27 Javascript
详解使用vue-admin-template的优化历程
2018/05/20 Javascript
jQuery实现html可联动的百分比进度条
2020/03/26 jQuery
Python面向对象程序设计类的封装与继承用法示例
2019/04/12 Python
python 抓包保存为pcap文件并解析的实例
2019/07/23 Python
Python3.9又更新了:dict内置新功能
2020/02/28 Python
Python json解析库jsonpath原理及使用示例
2020/11/25 Python
利用python进行文件操作
2020/12/04 Python
澳大利亚音乐商店:Bava’s Music City
2019/05/05 全球购物
SHEIN台湾:购买最新流行女装服饰
2019/05/18 全球购物
创业培训计划书
2014/05/03 职场文书
婚宴致辞
2015/07/28 职场文书
2016年会领导致辞稿
2015/07/29 职场文书
退伍军人感言
2015/08/01 职场文书
2016年八一建军节活动总结
2016/04/05 职场文书
利用Python+OpenCV三步去除水印
2021/05/28 Python
Oracle安装TNS_ADMIN环境变量设置参考
2021/11/01 Oracle