-
Notifications
You must be signed in to change notification settings - Fork 0
Open
Description
进程 线程
浏览器多进程
没打开一个tab 就多一个进程
browser进程 浏览器的主进程 只有一个
- 负责各个页面的管理,创建和销毁其他进程
- 网络资源的管理,下载等
- 负责浏览器界面显示,与用户交互。如前进,后退等
GPU进程:最多一个,用于3D绘制等
浏览器渲染进程(浏览器内核)(Renderer进程,内部是多线程的
[页面的渲染,JS的执行,事件的循环]都在这个进程里
默认每个Tab页面一个进程,互不影响。
主要作用为 页面渲染,脚本执行,事件处理等
多进程的优势
- 防止单 page crash 影响整个浏览器
- 避免第三方插件crash影响整个浏览器
- 多进程充分利用多核优势
- 方便使用沙盒模型隔离插件等进程,提高浏览器稳定性
渲染进程内部是有多线程的看看哪些线程吧
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==
-
创建worker时,js引擎向浏览器申请一个子线程, 子线程完全由浏览器控制 所以不能操作dom
-
js引擎线程与worker子线程通过特定的方式通信,需要通过序列化对象来与线程交互特定的数据
-
JS引擎是单线程的,这一点的本质仍然未改变,Worker可以理解是浏览器给JS引擎开的外挂,专门用来解决那些大量计算问题。
WebWorker与SharedWorker
1.WebWorker只属于某个页面,不会和其他页面的Render进程(浏览器内核进程)共享
所以Chrome在Render进程中(每一个Tab页就是一个render进程)创建一个新的线程来运行Worker中的JavaScript程序。
- 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线程继续接管,开始下一个宏任务(从事件队列中获取)
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels