Skip to content

浏览器 进程/线程 #23

@Lindysen

Description

@Lindysen

进程 线程
浏览器多进程
没打开一个tab 就多一个进程

browser进程 浏览器的主进程 只有一个

  1. 负责各个页面的管理,创建和销毁其他进程
  2. 网络资源的管理,下载等
  3. 负责浏览器界面显示,与用户交互。如前进,后退等

GPU进程:最多一个,用于3D绘制等

浏览器渲染进程(浏览器内核)(Renderer进程,内部是多线程的
[页面的渲染,JS的执行,事件的循环]都在这个进程里
默认每个Tab页面一个进程,互不影响。
主要作用为 页面渲染,脚本执行,事件处理等

多进程的优势

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

渲染进程内部是有多线程的看看哪些线程吧

1.GUI渲染线程

1.负责渲染浏览器界面,解析HTML,CSS,构建DOM树和RenderObject树,布局和绘制等。

2.当界面需要重绘(Repaint)或由于某种操作引发回流(reflow)时,该线程就会执行

3.GUI渲染线程与JS引擎线程是互斥的  当JS引擎执行时GUI线程会被挂起(相当于被冻结了),GUI更新会被保存在一个队列中等到JS引擎空闲时立即被执行。

2.JS引擎线程

1. 也称为JS内核,负责处理Javascript脚本程序

2. JS引擎线程负责解析Javascript脚本,运行代码。

3.GUI渲染线程与JS引擎线程是互斥的,所以如果JS执行的时间过长,这样就会造成页面的渲染不连贯,导致页面渲染加载阻塞。

3.事件触发线程

1.当JS引擎执行代码块如setTimeOut时(也可来自浏览器内核的其他线程,如鼠标点击、AJAX异步请求等),会将对应任务添加到事件线程中

2.当对应的事件符合触发条件被触发时,该线程会把事件添加到待处理队列的队尾,等待JS引擎的处理


由于JS的单线程关系,所以这些待处理队列中的事件都得排队等待JS引擎处理(当JS引擎空闲时才会去执行)

4.定时触发器线程

传说中的setInterval与setTimeout所在线程

为什么要单独的定时器线程?因为JavaScript引擎是单线程的,如果处于阻塞线程状态就会影响记计时的准确,因此很有必要单独开一个线程用来计时。

5.异步http请求线程

在XMLHttpRequest在连接后是通过浏览器新开一个线程请求

将检测到状态变更时,如果设置有回调函数,异步线程就产生状态变更事件,将这个回调再放入事件队列中。再由JavaScript引擎执行。

==WebWorker==

  1. 创建worker时,js引擎向浏览器申请一个子线程, 子线程完全由浏览器控制 所以不能操作dom

  2. js引擎线程与worker子线程通过特定的方式通信,需要通过序列化对象来与线程交互特定的数据

  3. JS引擎是单线程的,这一点的本质仍然未改变,Worker可以理解是浏览器给JS引擎开的外挂,专门用来解决那些大量计算问题。

WebWorker与SharedWorker

1.WebWorker只属于某个页面,不会和其他页面的Render进程(浏览器内核进程)共享

所以Chrome在Render进程中(每一个Tab页就是一个render进程)创建一个新的线程来运行Worker中的JavaScript程序。
  1. SharedWorker是浏览器所有页面共享的,不能采用与Worker同样的方式实现,因为它不隶属于某个Render进程,可以为多个Render进程共享使用

sharedWorker 由单独的进程管理, WebWorker只是属于render进程下的一个线程

css加载是否会阻塞dom树渲染?

css是由单独的下载线程异步下载的。

css加载不会阻塞DOM树解析(异步加载时DOM照常构建)

但会阻塞render树渲染(渲染时需等css加载完毕,因为render树需要css信息)

普通图层和复合图层

GPU中每个复合图层是单独绘制的  所以不相互影响


普通文档流内可以理解成一个复合图层 这里称为默认复合层,里面不管添加多少元素,其实都是在同一个复合图层中)
absolute fixed 布局 脱离文档流 还在这个复合图层



通过硬件加速,声明一个新的复合图层 他会单独分配资源, 当然也会脱离文档流,这样这个复合图层怎么改变,也不会影响默认复合层的重排重绘



如何生成新的复合图层
硬件加速

最常用的方式:translate3d、translateZ
opacity属性/过渡动画(需要动画执行的过程中才会创建合成层,动画没有开始或结束后元素还会回到之前的状态)

<video><iframe><canvas><webgl>等元素
其它,譬如以前的flash插件


absolute和硬件加速的区别

absolute 虽然脱离文档流 但是仍然在默认复合层内,就算absolute中信息改变时不会改变普通文档流中的render树,但是浏览器最终绘制的时候还是会整个复合层绘制,所以absolute中信息的改变,仍然会影响整个复合层的绘制。 

硬件加速是在另一个复合层中,他的信息改变不会引起原来的复合层改变(当然,内部肯定会影响属于自己的复合层)仅仅是引发最后的合成(输出视图)


复合图层的作用

一般一个元素开启硬件加速后会变成复合图层,可以独立于普通文档流中,改动后可以避免整个页面重绘,提升性能量,但是不要大量使用复合图层,否则由于资源消耗过度,页面反而会变的更卡



Event loop


J S中分为两种任务类型:macrotask和microtask在ECMAScript中,microtask称为jobs,macrotask可称为task

macrotask 中的事件都是放在一个事件队列里面,是由事件触发线程维护
可以理解是每次执行栈执行的代码就是一个宏任务(包括每次从事件队列中获取一个事件回调并放到执行栈中执行)

1.每一个task会从头到尾将这个任务执行完毕,不会执行其它
2.浏览器为了能够使得JS内部task与DOM任务能够有序的执行,会在一个task执行结束后,在下一个 task 执行开始前,对页面进行重新渲染 (task->渲染->task->...)


microtask 中所有微任务都是添加到微任务队列中,等待当前macrotask执行完毕后 这个队列由js引擎线程自己维护

1. 在当前task任务后,下一个task之前,在渲染之前
2.所以它的响应速度相比setTimeout(setTimeout是task)会更快,因为无需等渲染
3.在某一个macrotask执行完后,就会将在它执行期间产生的所有microtask都执行完毕(在渲染前)

microtask:Promise,process.nextTick等
macrotask:主代码块,setTimeout,setInterval等(可以看到,事件队列中的每一个事件都是一个macrotask)


总结一下运行机制

1.执行一个宏任务栈中(没有就从事件队列中获取)
2.执行过程中如果遇到微任务,就将它添加到微任务的任务队列中
3.宏任务执行完毕后,立即执行当前微任务队列中的所有微任务(依次执行
4. 当前宏任务执行完毕,开始检查渲染,然后GUI线程接管渲染
5. 渲染完毕后,JS线程继续接管,开始下一个宏任务(从事件队列中获取)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions