JavaScript定时机制、以及浏览器渲染机制 浅谈
昨晚,朋友拿了一道题问我:
a.onclick = function(){
setTimeout(function() {
//do something ...
},0);
};
JavaScript API 文档明确定义:setTimeout的第二个参数意义为隔多少毫秒后,回调方法就会被执行。那么可以推断出:这里设成0毫秒,就立即被执行了。
—————— 既然立即执行,为什么这段代码的作者为什么要 舍近求远?难道作者写代码的时候喝醉了?
显然不是!
这个问题 David Flanagan 在《Javascript 权威指南》中有阐述:当 setTimeout 的延迟时间设置为 0 的时候,回调函数不会马上执行,而是进入队列。
David Flanagan 在《Javascript权威指南》里并没有详细描述Javascript队列的具体运作方式,现在我来大致说一下这个问题。
JavaScript 引擎是单线程模式运行的,浏览器无论在什么时候都只且只有一个JavaScript线程在运行程序。
要说清楚这些问题,还得从浏览器内核处理定时器(setTimeout、setInterval)和响应浏览器事件说起。
浏览器内核实现允许多个线程异步执行,这些线程在内核制控下相互配合以保持同步。假设某一浏览器内核的实现至少有三个常驻线程:javascript引擎线程、界面渲染线程、浏览器事件触发线程。除些以外,也有一些执行完就终止的线程:如Http请求线程等,这些异步线程都会产生不同的异步事件。
下面通过一个图来阐明单线程的JavaScript引擎与另外那些线程是怎样互动通信的。虽然每个浏览器内核 (流行浏览器内核有:Trident[IE内核]、Gecko[Firefox内核]、Presto[Opera内核]、Webkit[Chrome、Safari] 等) 实现细节不同,但这其中的调用原理都是大同小异。

浏览器中的JavaScript引擎是基于事件驱动的。这里的事件可看作是浏览器派给它的各种任务,如调用setTimeout 添加一个任务,也可来自浏览器内核的其它线程,如界面元素鼠标点击事件、定时触发器时间到达通知、异步请求状态变更通知等。
从代码角度看来任务实体就是各种回调函数,JavaScript引擎一直等待着任务队列中任务的到来。由于单线程关系,这些任务得进行排队,一个接着一个被引擎处理。
图形界面渲染线程:
该线程负责渲染浏览器界面HTML元素,当界面需要重绘或由于某种操作引发回流时,该线程就会执行。
我今天想重点解释JavaScript定时机制,但这时有必要说说渲染线程,因为该线程与JavaScript引擎线程是互斥的!这一点Yahoo 前端攻城师在博客上有一篇详细文章描述这个问题。这也容易理解:因为JavaScript脚本是可操纵DOM元素,在修改这些元素属性同时渲染界面,那么渲染线程前后获得的元素数据就可能不一致了。
在JavaScript引擎运行脚本期间,浏览器渲染线程都是处于挂起状态的,也就是说被”冻结”了(题外话:YSlow优化网页建议指南指出:js文件要放在html内容的下面,就是因为加载 js 的时候,会阻塞 DOM树的构建。这一点可以再Yahoo工程师的前端优化方案里面看到)。
GUI事件触发线程:
JavaScript脚本的执行不影响html元素事件的触发,在Time1时间段内,用户点击鼠标键,点击事件被浏览器事件触发线程捕捉后,形成一个鼠标点击事件,对于JavaScript引擎线程来说,这事件是由其它线程异步传到任务队列尾的,由于引擎正在处理 Time1 时的任务,这个鼠标点击事件就会排队。
定时触发线程:
注意这里的浏览器模型定时计数器并不是由JavaScript引擎计数的,因为JavaScript引擎是单线程的,如果处于阻塞线程状态就不能计时,它必须依赖外部来计时并触发定时,所以队列中的定时事件也是异步事件。
后来朋友说道:既然JavaScript是单线程运行,那XMLHttpRequest 的异步链接是怎么回事?
其实异步请求是由浏览器新开一个线程请求!当请求的状态变更时,如果先前已设置回调,这异步线程就产生状态变更事件放到JavaScript引擎的处理队列中等待处理!
所以当任务被处理时,JavaScript引擎始终是单线程运行回调函数!
JavaScript定时机制、以及浏览器渲染机制 浅谈的更多相关文章
- [转]浏览器渲染机制——一定要放在body底部的js引用
转自:http://blog.csdn.net/u012251421/article/details/50536265 说明: 本文提到的浏览器均是指Chrome. “script标签“指的都是普通的 ...
- 转:JavaScript定时机制、以及浏览器渲染机制 浅谈
昨晚,朋友拿了一道题问我: a.onclick = function(){ setTimeout(function() { //do something ... },0); }; //~~~ 我只知道 ...
- 理解WebKit和Chromium: Chromium WebView和Chrome浏览器渲染机制
转载请注明原文地址:http://blog.csdn.net/milado_nju ## 数据对比 前面介绍过Chromium WebView的时候,说过有关ChromiumWebView同Chrom ...
- 网页性能优化:防止JavaScript、CSS阻塞浏览器渲染页面
网页中引用的外部文件: JavaScritp.CSS 等常常会阻塞浏览器渲染页面.假设在 <head> 中引用的某个 JavaScript 文件由于各种不给力需要2秒来加载,那么浏览器渲染 ...
- 转---JS 一定要放在 Body 的最底部么?聊聊浏览器的渲染机制
作者:德来 segmentfault.com/a/1190000004292479 如有好文章投稿,请点击 → 这里了解详情 一.从一个面试题说起 面试前端的时候我喜欢问一些看上去是常识的问题.比如: ...
- 关于JavaScript定时机制的总结
要理解JavaScript的定时机制,就要知道JavaScript的运行机制. 首先声明,JavaScript是单线程运行(JavaScript引擎线程)事件驱动. 一.浏览器中有多个线程 一款浏览器 ...
- JavaScript可否多线程? 深入理解JavaScript定时机制
JavaScript的setTimeout与setInterval是两个很容易欺骗别人感情的方法,因为我们开始常常以为调用了就会按既定的方式执行, 我想不少人都深有同感, 例如 setTimeout( ...
- 深入理解JavaScript定时机制和定时器注意问题
容易欺骗别人感情的JavaScript定时器 JavaScript的setTimeout与setInterval是两个很容易欺骗别人感情的方法,因为我们开始常常以为调用了就会按既定的方式执行, 我想不 ...
- JavaScript可否多线程? 深入理解JavaScript定时机制(转载)
说明:最近写 js 时需要用setinterval函数做定时操作,谁知道,刚开始后运行完好,但一段时间后他就抽风了,定时任务运行的时间间隔越来越短,频率加快,这是一个完全不能容忍的问题,带着一个可以出 ...
随机推荐
- 使用Log4net记录日志
首先说说为什么要进行日志记录.在一个完整的程序系统里面,日志系统是一个非常重要的功能组成部分.它可以记录下系统所产生的所有行为,并按照某种规范表达出来.我们可以使用日志系统所记录的信息为系统进行排错, ...
- javascript 用call来继承实例属性
xxx.call(thisObj, arg1,...)的调用可以改变当前函数的执行环境为传入的thisObj对象.利用这一点可以实现继承————当前的对象获得XXX的属性和方法. 例子: functi ...
- jQuery常用及基础知识总结(一)
Attribute: $(”p”).addClass(css中定义的样式类型); 给某个元素添加样式$(”img”).attr({src:”test.jpg”,alt:”test Image”}); ...
- java.lang.RuntimeException: java.lang.NoSuchMethodException:
[java] 15/12/19 14:09:46 INFO mapred.JobClient: Task Id : attempt_201512182036_0017_m_000000_0, Stat ...
- (转)Eclipse中使用Ant
Eclipse中使用Ant 分类: JAVA 工具 服务器2014-08-05 09:59 5507人阅读 评论(0) 收藏 举报 anteclipse http://286.iteye.com/bl ...
- fsck害了我很久了,必须关掉,因为他每次打卡都要推迟数十分钟。
http://crashmag.net/disable-filesystem-check-fsck-at-boot-time Disable the filesystem check (fsck) a ...
- JQuery实现仿腾讯的固定导航栏
1.描述 窗口滚动一定高度之后才让导航栏固定 2.要点 浏览器滚动的事件:$(window).scroll(functiuon(){ 文档滚过的高度: $(doucment).scrollTop(); ...
- php dependency innjection
You’ve probably heard of the acronym SOLID by now, which is an object oriented programming paradigm ...
- tp框架链接数据库的基本操作
<?php namespace Admin\Controller; use Think\Controller; class MainController extends Controller { ...
- 关于Java通过JNI调用C 动态链接库(DLL)
JNI介绍 用JNI实现Java和C语言的数据传递 JNI原理分析和详细步骤截图说明 jni的JNIEnv指针和jobject指针 JNI实现回调| JNI调用JAVA函数|参数和返回值的格式 Jni ...