浏览器和浏览器的事件循环

简介: 我们可以用浏览器打开很多的网页,关闭其中的任何一个对于其他的网页没有影响,这个大家都明白,因为浏览器是多进程的。说到进程,不得不提到的还有线程,关于他们俩个的区别:

一、线程和进程

我们可以用浏览器打开很多的网页,关闭其中的任何一个对于其他的网页没有影响,这个大家都明白,因为浏览器是多进程的。说到进程,不得不提到的还有线程,关于他们俩个的区别:

进程是cpu分配资源的最小单位;

线程是进程的最小调度单位;

进程和线程都是一个时间段的描述,是CPU工作时间段的描述,不过是颗粒大小不同。

对于浏览器,每个tab页面就是一个进程。以多进程形式,允许多个任务同时运行; 以多线程形式,允许单个任务分成不同的部分运行; 提供协调机制,一方面防止进程间和线程间产生冲突,另一方面允许进程之间和线程之间共享资源。

二、浏览器多进程

浏览器包括以下进程:

  • 主进程:负责协调和主控,只有一个;
  • 第三方插件:每个类型一个进程;
  • GPU进程:3D绘制;
  • render渲染进程:浏览器渲染进程,每个tab一个进程互不影响;

再来张图,我比较喜欢看图:

我们前端需要重点了解的是 浏览器渲染多进程

三、浏览器多线程

浏览器是多线程,一个页面包含以下线程:

  • GUI线程:负责浏览器页面渲染,解析html,css构建,Dom树子和renderObject对象,布局和绘制;
  • js引擎线程:负责执行js脚本,先渲染页面后执行js;
  • 事件触发线程:事件触发时,负责把事件放入队列,等待执行;
  • 定时器线程:将settimeout和setinterval执行函数再触发时放入队列等待执行;
  • http请求线程:监听请求状态变更,将相应函数放入队列,等待执行;

再将以上内容用图片描述一下:

四、浏览器事件循环

第三部分提到了“队列”,“队列”的另一个伙伴叫做“js执行栈”。 js的引擎机制由“执行栈”和“队列”组成;所有js代码都在栈中执行,队列中的,等待栈中js执行完毕后,再拿到栈中执行。

那哪些js是直接在栈中执行,哪些是需要在队列中等待执行的呢?

解答上面的这个问题前,需要先了解 “宏任务” 和 “微任务”。

  • 宏任务:script(整体代码),setTimeout,setInterval,ie支持的setImmediate,MessageChannel,
  • 微任务:es6的Promise的then,Object.observe(已废弃),MutationObserver(html5新特性)

js在执行过程中先执行宏任务,有以下的情况:

  • 如果在执行过程中产生了微任务:那么,等本轮的宏任务完成后立刻去执行微任务。
  • 在执行过程中产生宏任务:等本轮的宏任务完成后立刻去执行宏任务。
  • 在执行过程中产生宏任务和微任务:等本轮的宏任务完成后,先去清空微任务列表,再去执行下一个宏任务。(在执行下个宏任务过程中,任然按照以上分析的情况来处理)

来段代码解释一下上面的描述:

console.log("我是开始");

setTimeout(function() {
  console.log('setTimeout');
}, 0);

Promise.resolve().then(function() {
  console.log('promise1');
}).then(function() {
  console.log('promise2');
});

console.log('我是结束');
复制代码

以上的打印结果顺序:

我是开始 我是结束 promise1 promise2 setTimeout

分析一下:

console.log("我是开始");         //主程序代码(宏任务1)

setTimeout(function() {         //产生了一个新的宏任务2——————放入宏任务队列
  console.log('setTimeout');
}, 0);

Promise.resolve().then(function() {    //产生了微任务1——————放入微任务队列
  console.log('promise1');
}).then(function() {                   //产生了微任务2——————放入微任务队列
  console.log('promise2');
});

console.log('我是结束');        //主程序代码(宏任务1)
复制代码

按照以上的注释,先执行宏任务1 ,将本轮宏任务全部执行后,打印出“我是开始”,“我是结束”

刚才也讲过,每执行完一个宏任务后,如果有微任务就去清空微任务队列,现在看下,微任务列表现在有两个微任务,那么就将 promise1 promise2 打印出来。多个微任务是按照先入先出的顺序执行。

清空了微任务列表,再看看是否还有宏任务,发现宏任务列表还有个setTimeout,然后就把它执行以下,打印出结果 setTimeout。同样,宏任务队列有很多个,也是按照先入先出的顺序执行。

再来张图:

以上,就是我对浏览器事件循环的理解,欢迎大家批评指正。

参考文章:

  1. 来自Google开发者Jake:jakearchibald.com/2015/tasks-…
  2. 来自微信公众号“前端早读课的文章”:mp.weixin.qq.com/s?__biz=MjM…

原文发布时间为:2018年07月01日

本文作者:Liz栗子

本文来源:掘金 如需转载请联系原作者


相关文章
|
13天前
|
存储 JavaScript 网络协议
浏览器与 Node 的事件循环
浏览器和Node.js的事件循环是异步操作的核心机制。它们通过管理任务队列和回调函数,确保程序在处理耗时任务时不会阻塞主线程,从而实现高效、响应式的应用开发。
|
6月前
|
Web App开发 JavaScript 前端开发
浏览器与Node.js事件循环:异同点及工作原理
浏览器与Node.js事件循环:异同点及工作原理
|
4月前
|
存储 JavaScript 前端开发
在?聊聊浏览器事件循环机制
在?聊聊浏览器事件循环机制
45 0
|
6月前
|
存储 前端开发 JavaScript
揭秘浏览器的事件循环:让网页动起来的幕后英雄
揭秘浏览器的事件循环:让网页动起来的幕后英雄
揭秘浏览器的事件循环:让网页动起来的幕后英雄
|
JavaScript 前端开发
浏览器中的事件循环和Node.js中事件循环的区别(经典面试题)
浏览器中的事件循环和Node.js中事件循环的区别(经典面试题)
764 0
|
移动开发 前端开发 HTML5
浏览器和 Node 中的事件循环有什么区别?
浏览器和 Node 中的事件循环有什么区别?
98 0
|
消息中间件 前端开发 JavaScript
浏览器中的事件循环
浏览器中的事件循环
90 1
|
消息中间件 Web App开发 监控
浏览器原理 14 # 消息队列和事件循环
浏览器原理 14 # 消息队列和事件循环
202 0
浏览器原理 14 # 消息队列和事件循环
|
JavaScript 前端开发 API
JavaScript 事件循环(EventLoop) —— 浏览器 & Node
JavaScript 事件循环(EventLoop) —— 浏览器 & Node
108 0
|
存储 Web App开发 缓存
浏览器专题系列 - 事件循环机制
浏览器专题系列 - 事件循环机制