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函数做定时操作,谁知道,刚开始后运行完好,但一段时间后他就抽风了,定时任务运行的时间间隔越来越短,频率加快,这是一个完全不能容忍的问题,带着一个可以出 ...
随机推荐
- TCP 连接中的TIME_WAIT
原文:http://blog.csdn.net/wangpengqi/article/details/17245349 这就有个细节,一次http请求,谁会先断开TCP连接?什么情况下客户端先断,什么 ...
- gdb 远程调试android进程 -转
什么是gdb 它是gnu组织开发的一个强大的unix程序调试工具,我们可以用它来调试Android上的C.C++代码. 它主要可以做4件事情: 随心所欲地启动你的程序. 设置断点,程序执行到断点处会停 ...
- 第一个元素<flout>写了,想在他的旁边加一个元素.IE6会出现缝隙. 不要用margin撑开,要用flout
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...
- 深入浅出Ajax(一)
客户端: <script type="text/javascript"> window.onload = initPage; function initPage() { ...
- 解决Ubuntu系统中文乱码显示问题,终端打开文件及查看目录
解决Ubuntu系统中文乱码显示问题 [日期:2014-02-20] 来源:Linux社区 作者:njchenyi [字体:大 中 小] 我是先安装了Ubuntu 12.04 Server,然后 ...
- 基于心跳的socket长连接
http://coach.iteye.com/blog/2024444 基于心跳的socket长连接 博客分类: http socket 案例: 心跳: socket模拟网页的报文连接某个网站,创建t ...
- 「CSS3 」3D效果 & 透视
CSS3d透视 perspective属性 原文链接:https://segmentfault.com/a/1190000003843764
- Android音频系统之音频框架
1.1 音频框架 转载请注明,From LXS, http://blog.csdn.net/uiop78uiop78/article/details/8796492 Android的音频系统在很长一段 ...
- [Big Data]从Hadoop到Spark的架构实践
摘要:本文则主要介绍TalkingData在大数据平台建设过程中,逐渐引入Spark,并且以Hadoop YARN和Spark为基础来构建移动大数据平台的过程. 当下,Spark已经在国内得到了广泛的 ...
- boost库之shared_ptr
shared_ptr 编辑 目录 1简介 2作用 3历史 4概要 5用法 ▪ 删除共享对象 ▪ 标准容器 1简介编辑 shared_ptr是一种智能指针(smart pointer). 2作用编辑 s ...