博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
浏览器内核常驻线程
阅读量:5295 次
发布时间:2019-06-14

本文共 2180 字,大约阅读时间需要 7 分钟。

浏览器内核常驻线程

  1. 浏览器 GUI 渲染线程
  2. JavaScript 引擎线程
  3. 浏览器定时触发器线程
  4. 浏览器事件触发线程 
  5. 浏览器 http 异步请求线程

浏览器 GUI 渲染线程 和 JavaScript 引擎线程之间是互斥的

在debug里面check一下如下代码的效果即可知道

var sleep = function(time) {    var date = new Date();     while(new Date() - date <= time) {}}document.body.innerHTML = '123';sleep(3000)

 

原理也很简单:

  • GUI渲染线程负责渲染浏览器界面的HTML元素, 当界面需要重绘(repaint)由于某种操作引发回流(reflow)时,该线程就会执行。
  • 因为 JavaScript脚本是可操纵DOM元素, 在修改这些元素属性同时渲染界面, 那么渲染线程前后获得的元素数据就可能不一致了。
  • 所以在脚本中执行对界面进行更新操作, 如添加结点,删除结点或改变结点的外观等更新并不会立即体现出来, 这些操作将保存在一个队列中,待JavaScript引擎空闲时才有机会渲染出来。

所以当遇到在js引擎运算量较大的时候, 又想及时调用GUI渲染,可以做如下修改:

var sleep = function(time) {    var date = new Date();     while(new Date() - date <= time) {}}document.body.innerHTML = '123';setTimeout(function() {   sleep(3000);}, 0);

 

JavaScript 引擎线程

事件驱动(event driven)机制

事件驱动一般通过事件循环(event loop)和事件队列(event queue)来实现的。

假定浏览器中有一个专门用于事件调度的实例(该实例可以是一个线程,可以称之为事件分发线程event dispatch thread),该实例的工作就是一个不结束的循环,从事件队列中取出事件,处理所有很事件关联的回调函数(event handler)。

注意回调函数是在Javascript的主线程中运行的,而非事件分发线程中,以保证事件处理不会发生阻塞。  

Event loop code

 

如果队列非空,引擎就从队列头取出一个任务,直到该任务处理完,即返回后引擎接着运行下一个任务, 在任务没返回前队列中的其它任务是没法被执行的.

与其它线程间的通信

  

浏览器 http 异步请求线程

浏览器对同一域名进行请求的并发连接数是有限制的,result10 in IE 8, 6 in Firefox 3+ and Chrome 5+。详情参考demo: 

XMLHttpRequest在连接后是通过浏览器新开一个线程请求, 将检测到状态变更时,如果设置有回调函数,异步线程就产生状态变更事件放到 JavaScript引擎的处理队列中等待处理

 

浏览器事件触发线程 

接受浏览器里面的操作事件响应。如在监听到鼠标、键盘等事件的时候, 如果有事件句柄函数,就讲对应的任务压入队列。

 

浏览器定时触发线程

浏览器模型定时计数器并不是由JavaScript引擎计数的, 因为JavaScript引擎是单线程的, 如果处于阻塞线程状态就会影响记计时的准确, 它必须依赖外部来计时并触发定时。

setTimeout & setInterval

setTimeout:在参数指定的时间后将待执行方法放到执行队列中, 如果队列中没有其他方法等待,则会立即执行setTimeout指定的方法。
setIinterVal:  定时触发器线程每间隔指定的时间将指定方法放入到执行队列中,  当函数执行时,如果发现同一个定时器已经有多个在等待执行的任务,只会执行1次。后面的会被忽略掉。 
 
var sleep = function(time) {    var date = new Date();     while(new Date() - date <= time) {}}var time = new Date();var a = setInterval(function(){    sleep(200);    console.log(new Date() - time);    if(new Date() - time > 700) clearInterval(a);}, 100);  //output 303506708

 

以上代码表示在700时间内,一共有7个timer callback被压入队尾, clearInterval后, 只有3个timer对应的callback得到执行。 所以这种情况可以采用setTimeout的方式来让执行结果更加符合开发预期:

var a = setTimeout(function(){    sleep(200);    setTimeout(arguments.callee, 100)}, 100);

 

转自:

转载于:https://www.cnblogs.com/lidgblogs/p/7427187.html

你可能感兴趣的文章
使用gitbash来链接mysql
查看>>
SecureCRT的使用方法和技巧(详细使用教程)
查看>>
右侧导航栏(动态添加数据到list)
查看>>
81、iOS本地推送与远程推送详解
查看>>
虚拟DOM
查看>>
uva 11468 Substring
查看>>
自建数据源(RSO2)、及数据源增强
查看>>
BootStrap2学习日记2--将固定布局换成响应式布局
查看>>
关于View控件中的Context选择
查看>>
2018icpc徐州OnlineA Hard to prepare
查看>>
Spark的启动进程详解
查看>>
使用命令创建数据库和表
查看>>
数据库的高级查询
查看>>
[YTU]_2443 ( C++习题 复数类--重载运算符3+)
查看>>
sdut_1189
查看>>
机器视觉:SSD Single Shot MultiBox Detector
查看>>
国内外免费电子书(数学、算法、图像、深度学习、机器学习)
查看>>
狄利克雷过程(Dirichlet Process)
查看>>
五子棋项目的实现(二)博弈树算法的描述
查看>>
Hibernate : Disabling contextual LOB creation as createClob() method threw error
查看>>