最后下面的渲染进程可能有多个(每一个tab页面浏览器都会启动一个渲染进程)css
浏览器的主进程(负责协调、主控),只有一个。html
负责浏览器界面显示,与用户交互。如前进,后退等web
负责各个页面的管理,建立和销毁其余进程segmentfault
将Renderer进程获得的内存中的Bitmap,绘制到用户界面上浏览器
网络资源的管理,下载等服务器
每种类型的插件对应一个进程,仅当使用该插件时才建立网络
最多一个,用于3D绘制等多线程
默认每一个Tab页面都会产生一个渲染进程,互不影响。主要做用为
页面渲染,脚本执行,事件处理等dom
打开Chrome Shift+Esc;咱们能够看到进程状况,Chrome图标就是Browser主进程异步
避免单个page crash影响整个浏览器
避免第三方插件crash影响整个浏览器
多进程充分利用多核优点
方便使用沙盒模型隔离插件等进程,提升浏览器稳定性
简单点理解:若是浏览器是单进程,那么某个Tab页崩溃了,就影响了整个浏览器,体验有多差;同理若是是单进程,插件崩溃了也会影响整个浏览器;并且多进程还有其它的诸多优点,固然内存等资源消耗也会更大
负责渲染浏览器界面,解析HTML,CSS,构建DOM树和RenderObject树,布局和绘制等。
当界面须要重绘(Repaint)或因为某种操做引起回流(reflow)时,该线程就会执行
注意,GUI渲染线程与JS引擎线程是互斥的,当JS引擎执行时GUI线程会被挂起(至关于被冻结了),GUI更新会被保存在一个队列中等到JS引擎空闲时当即被执行。
为何互斥:因为 JS 是能够操做 DOM 的,若是同时修改元素属性并同时渲染界面(即 JS线程和UI线程同时运行), 那么渲染线程先后得到的元素就可能不一致了(简单说就是js修改dom后没有从新渲染成功)
也称为JS内核,负责处理Javascript脚本程序。(例如V8引擎)
JS引擎线程负责解析Javascript脚本,运行代码。
JS引擎一直等待着任务队列中任务的到来,而后加以处理,一个Tab页(renderer进程)中不管何时都只有一个JS线程在运行JS程序
一样注意,GUI渲染线程与JS引擎线程是互斥的,因此若是JS执行的时间过长,这样就会形成页面的渲染不连贯,致使页面渲染加载阻塞。
归属于浏览器而不是JS引擎,用来控制事件循环(能够理解,JS引擎本身都忙不过来,须要浏览器另开线程协助)
当JS引擎执行代码块如setTimeOut时(也可来自浏览器内核的其余线程,如鼠标点击、AJAX异步请求等),会将对应任务添加到事件线程中
当对应的事件符合触发条件被触发时,该线程会把事件添加到待处理队列的队尾,等待JS引擎的处理
注意,因为JS的单线程关系,因此这些待处理队列中的事件都得排队等待JS引擎处理(当JS引擎空闲时才会去执行)
传说中的setInterval与setTimeout所在线程
浏览器定时计数器并非由JavaScript引擎计数的,(由于JavaScript引擎是单线程的, 若是处于阻塞线程状态就会影响记计时的准确)
所以经过单独线程来计时并触发定时(计时完毕后,添加到事件队列中,等待JS引擎空闲后执行)
注意,W3C在HTML标准中规定,规定要求setTimeout中低于4ms的时间间隔算为4ms。
在XMLHttpRequest在链接后是经过浏览器新开一个线程请求
将检测到状态变动时,若是设置有回调函数,异步线程就产生状态变动事件,将这个回调再放入事件队列中。再由JavaScript引擎执行。
因为JavaScript是可操纵DOM的,若是在修改这些元素属性同时渲染界面(即JS线程和UI线程同时运行),那么渲染线程先后得到的元素数据就可能不一致了。
所以为了防止渲染出现不可预期的结果,浏览器设置GUI渲染线程与JS引擎为互斥的关系,当JS引擎执行时GUI线程会被挂起,
GUI更新则会被保存在一个队列中等到JS引擎线程空闲时当即被执行。
从上述的互斥关系,能够推导出,JS若是执行时间过长就会阻塞页面。
譬如,假设JS引擎正在进行巨量的计算,此时就算GUI有更新,也会被保存到队列中,等待JS引擎空闲后执行。
而后,因为巨量计算,因此JS引擎极可能好久好久后才能空闲,天然会感受到巨卡无比。
因此,要尽可能避免JS执行时间过长,这样就会形成页面的渲染不连贯,致使页面渲染加载阻塞的感受。
JavaScript引擎是单线程运行的,JavaScript中耗时的I/O操做都被处理为异步操做,它们包括键盘、鼠标I/O输入输出事件、窗口大小的resize事件、定时器(setTimeout、setInterval)事件、Ajax请求网络I/O回调等。当这些异步任务发生的时候,它们将会被放入浏览器的事件任务队列中去,等到JavaScript运行时执行线程空闲时候才会按照队列先进先出的原则被一一执行,但终究仍是单线程。
建立Worker时,JS引擎向浏览器申请开一个子线程(子线程是浏览器开的,彻底受主线程控制,并且不能操做DOM)
JS引擎线程与worker线程间经过特定的方式通讯(postMessage API,须要经过序列化对象来与线程交互特定的数据)
//主线程 main.js var worker = new Worker("worker.js"); worker.onmessage = function(event){ // 主线程收到子线程的消息 }; // 主线程向子线程发送消息 worker.postMessage({ type: "start", value: 12345 }); //web worker.js onmessage = function(event){ // 收到 }; postMessage({ type: "debug", message: "Starting processing..." });
浏览器使用流式布局模型 (Flow Based Layout)。
有了RenderTree,咱们就知道了全部节点的样式,而后计算他们在页面上的大小和位置,最后把节点绘制到页面上。
当Render Tree中部分或所有元素的尺寸、结构、或某些属性发生改变时,浏览器从新渲染部分或所有文档的过程称为回流。
当页面中元素样式的改变并不影响它在文档流中的位置时(例如:color、background-color、visibility等),浏览器会将新样式赋予给元素并从新绘制它,这个过程称为重绘。