浏览器运行原理

浏览器多进程、js单线程,全面梳理js运行机制

首先抛出几个关键点-----浏览器是多线程的(可以在浏览器的任务管理器中验证),js是单线程(众所周知?)
浏览器运行原理
可以看出,浏览器有一个主进程,并且每开一个tab,就会新开一个进程。浏览器多进程的原因做点儿解释:
相比于单进程浏览器,多进程有如下优点

  • 避免单个page crash影响整个浏览器
  • 避免第三方插件crash影响整个浏览器
  • 多进程充分利用多核优势方便使用沙盒模型隔离插件等进程,提高浏览器稳定性

简单点理解:如果浏览器是单进程,那么某个Tab页崩溃了,就影响了整个浏览器,体验有多差;同理如果是单进程,插件崩溃了也会影响整个浏览器;而且多进程还有其它的诸多优势。。。

下面清点一下浏览器各个主要进程的工作(我的理解,把一个个进程当作一个个工厂,要产出一件合格的产品,需要各个工厂各司其职。)

  1. Browser进程:浏览器的主进程(负责协调、主控),只有一个。作用有
  2. 负责浏览器界面显示,与用户交互。如前进,后退等
  3. 负责各个页面的管理,创建和销毁其他进程 将Renderer进程得到的内存中的Bitmap,绘制到用户界面上 网络资源的管理,下载等
  4. 第三方插件进程:每种类型的插件对应一个进程,仅当使用该插件时才创建
  5. GPU进程:最多一个,用于3D绘制等
  6. 浏览器渲染进程(浏览器内核)(Renderer进程,内部是多线程的):默认每个Tab页面一个进程,互不影响。主要作用为页面渲染,脚本执行,事件处理等

作为前端工程师,我们应该最为关心的是浏览器众多进程中的渲染进程
知识点:1,渲染进程是多线程的,那么下面梳理一下此进程中有哪些需要关注的线程呢
简单比喻:将一个线程视作一个工厂,这个多人协作(多线程)的工厂。那么这个工厂中有哪些工人呢?

  1. GUI渲染线程
    主要职责:负责渲染浏览器界面,解析HTML,CSS,构建DOM树和RenderObject树***,布局和绘制等,当界面需要重绘,或由于某种操作引发回流(reflow)时,该线程就会执行
    值得注意的是:GUI渲染线程与JS引擎线程是互斥的,当JS引擎执行时GUI线程会被挂起(相当于被冻结了),GUI更新会被保存在一个队列中等到
    JS引擎空闲时*立即被执行。

  2. js引擎线程
    该线程也被称作JS内核,负责处理Javascript脚本程序。(例如V8引擎),该线程负责解析Javascript简本,运行代码。 JS引擎一直等待着任务队列的任务到来,然后加以处理,一个tab(rederer进程)中有无论什么时候都只有一个JS线程在运行JS程序。由于前面所说的GUI渲染线程和JS引擎线程是互斥的,所以如果JS执行时间过长,这样就会造成页面的渲染不连贯,导致页面渲染加载阻塞

  3. 事件触发线程
    归属于浏览器而不是JS引擎,(不才的理解,事件本身是归属于事件触发线程,只是事件的响应是JS引擎来处理的)用来控制事件的循环(原作者的话:可以理解为JS引擎自己都忙不过来,需要浏览器另开线程协助)当JS引擎执行代码块如setTimeout时(也可能时鼠标点击,或者ajax等),会将对应任务添加到时间线程中;当对应事件符合触发条件时,该线程会把事件处理添加到待处理队列的队尾,等待JS引擎的处理;注意,由于JS的单线程关系,所以这些待处理队列中的事件都得排队等待JS引擎处理(当JS引擎空闲时才会去处理)

  4. 定时器触发线程
    传说中的setTime和setInterval所在的线程,浏览器定时计数器并不是由JS引擎计数的(这点想也想的明白,JS引擎是单线程的,而且计时器是异步的)
    因此通过单独线程来计时(计时完毕,添加事件到事件队列中,等待JS引擎空闲后执行)

  5. 异步HTTP请求线程
    在XMLHttpRequest连接后,通过浏览器新开一个线程请求,将检测到状态变更时,如果设置有回调函数,异步线程就产生状态变更事件,将这个回调再放到事件队列中,再由Javascript引擎执行
    巩固一哈:
    浏览器运行原理

未完待续…