浏览器进程与线程

浏览器进程和线程

浏览器

浏览器是多进程的。每一个Tab页就是一个独立的进程。

  • 浏览器进程(主进程):个人理解为“管家”的角色,它控制着浏览器的各个任务,页面展示、网络请求、历史回退、前进等等
  • 第三方插件进程:管理第三方插件
  • GPU线程:用于3D绘制
  • 渲染进程:浏览器内核,多线程。主要负责页面渲染、脚本执行、事件循环等。对前端来说,最重要的进程。

浏览器多进程优势:

  • 防止单个页面或者插件崩溃影响整个浏览器的运行。
  • 可以充分利用浏览器多核的优势。
  • 方便使用沙盒模型隔离插件等进程,提高浏览器稳定性。

浏览器内核(渲染进程)

渲染进程是多线程的。它包含一下几大线程:

  • GUI线程
    • 它负责页面的渲染、布局、解析HTML、CSS、渲染DOM树。
    • 当页面发生重绘或者回流的时候,就会触发该线程
    • 它和JS引擎线程互斥
  • JS引擎线程
    • 负责程序的解析和执行
  • 事件触发线程
    • 它控制事件循环,管理着一个事件任务队列TaskQueue
    • 当异步任务满足条件时,会将该异步任务的回调函数放入到JS引擎线程所在的执行栈中执行
  • 定时触发器线程
    • setTimeOut 和 setInterval 所在的线程
    • 定时器任务的计时不是由JS引擎计时的,而是由该线程控制
    • 当定时任务计时完成之后,会通知事件触发线程
    • W3C在HTML标准中规定,规定要求setTimeout中低于4ms的时间间隔算为4ms。
  • 异步http请求线程
    • 一个独立的ajax请求线程
    • 当请求完成之后,会通知事件触发线程

为什么GUI线程和JS引擎线程互斥

因为JS是可以操作DOM的,如果使用JS操作DOM的同时,GUI线程也在渲染DOM,那么渲染完成之后的元素可能就不是之前的元素了

为什么JS引擎是单线程

  • 创建JavaScript语言的时候,多进程多线程的架构并不流行,硬件支持度不高
  • 多进程多线程操作需要加锁,操作成本较高,较为复杂
  • 如果多个线程同时操作一个DOM,那么结果会是不可预料的
  • 线程之间资源共享

Event Loop

  • JS的任务分为同步任何和异步任务的
  • 同步任务都在JS引擎的执行栈上执行
  • 事件触发线程管理一个任务队列,TaskQueue,当异步任务满足条件时,事件触发线程会将其放到任务队列当中,当主线程(JS引擎线程)执行完执行栈中的任务之后,会读取任务队列中的任务,如果有,就将可执行的异步任务的回调函数推入到执行栈中,开始执行。如果没有,则再次向事件触发线程发起询问,直到有为止。

代码解释:

let timerCallback = function() {
  console.log('timerCallback');
};
let httpCallback = function() {
  console.log('httpCallback');
}

// 同步任务
console.log('同步任务1');
// 同步任务
// 通知定时器线程 1s 后将 timerCallback 交由事件触发线程处理
// 1s 后事件触发线程将 timerCallback 加入到事件队列中
setTimeout(timerCallback,1000);
// 同步任务
// 通知异步http请求线程发送网络请求,请求成功后将 httpCallback 交由事件触发线程处理
// 请求成功后事件触发线程将 httpCallback 加入到事件队列中
$.get('www.xxxx.com',httpCallback);
// 同步任务
console.log('同步任务2');
//...
// 所有同步任务执行完后
// 询问事件触发线程在事件事件队列中是否有需要执行的回调函数
// 如果没有,一直询问,直到有为止
// 如果有,将回调事件加入执行栈中,开始执行回调代码

总结:

  • JS引擎线程只执行执行栈中的事件
  • 执行栈中的代码执行完毕,就会读取事件队列中的事件
  • 事件队列中的回调事件,是由各自线程插入到事件队列中的
  • 如此循环

宏任务、微任务

宏任务:可以理解为浏览器级别的任务。主代码块,setTimeout,setInterval等,都属于宏任务

微任务:JS引擎级别的任务。Promise,process.nextTick等,属于微任务

执行顺序:

  • 当前代码块对应的宏任务
  • 当前宏任务结束之后,下一个宏任务开始之前,执行当前对列的微任务
  • GUI引擎渲染
  • 下一个宏任务
  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!