进程
-
CPU 分配资源的最小单位
-
进行中的程序及其所使用的内存和资源
-
CPU 通过时间片的轮转来实现多进程
浏览器
- Chrome:每打开一个Tab页就会产生一个进程
浏览器包含哪些进程
Browser进程
-
浏览器的主进程(负责协调、主控),该进程只有一个
-
界面显示,用户交互
-
将渲染(Renderer)进程得到的内存中的Bitmap(位图),绘制到用户界面上
-
网络资源的管理,下载等
第三方插件进程
- 每种类型的插件对应一个进程,当使用该插件时才创建
GPU进程
- 该进程也只有一个,3D渲染
渲染进程
-
浏览器内核(Renderer进程,内部是多线程)
-
每个Tab页面都有一个渲染进程,互不影响
-
主要作用为页面渲染,脚本执行,事件处理等
为什么浏览器要多进程
-
如果浏览器是单进程,那么某个Tab页崩溃会影响了整个浏览器
- 同理如果插件崩溃了也会影响整个浏览器。
-
浏览器进程有很多,每个进程又有很多线程,都会占用内存
渲染进程
GUI渲染线程
-
负责渲染浏览器界面,解析HTML,CSS,构建DOM树,RenderObject树,布局,绘制
-
解析html代码(HTML代码本质是字符串)转化为浏览器认识的节点,生成DOM树(DOM Tree)
-
解析css,生成CSSOM(CSS规则树)
-
把DOM Tree 和CSSOM结合,生成Rendering Tree(渲染树)
-
-
修改颜色或者背景色,页面就会重绘(Repaint)
-
修改元素的尺寸,页面就会回流(Reflow)
-
当页面需要Repaing和Reflow时,GUI线程执行,绘制页面
-
回流(Reflow)比重绘(Repaint)的成本要高,要尽量避免Reflow和Repaint
-
GUI渲染线程与JS引擎线程是互斥的
-
当JS引擎执行时GUI线程会被挂起(相当于被冻结了)
-
GUI更新会被保存在一个队列中等到JS引擎空闲时立即被执行
-
JS引擎线程
-
JS引擎线程就是JS内核,负责处理Javascript脚本程序(例如V8引擎)
-
负责解析Javascript脚本,运行代码
-
JS引擎一直等待着任务队列中任务的到来,再加以处理
-
浏览器同时只能有一个JS引擎线程在运行JS程序,所以js是单线程运行的
-
一个Tab页(renderer进程)中无论什么时候都只有一个JS线程在运行JS程序
-
-
GUI渲染线程与JS引擎线程是互斥的,js引擎线程会阻塞GUI渲染线程
-
JS执行时间过长,造成页面的渲染不连贯,导致页面渲染加载阻塞(就是加载慢)
-
浏览器渲染的时候遇到
-
js执行时间太长就会造成页面卡顿的情况
-
defer:JS 延迟执行,直到 DOM 渲染完 -
async:不会让脚本阻塞文档
-
-
事件触发线程
- onClick methods handle task queue
-
属于浏览器而不是JS引擎,用来控制事件循环,并且管理着一个事件队列(task queue)
-
事件绑定和异步操作(如setTimeOut,也可来自浏览器内核的其他线程,如鼠标点击、AJAX异步请求等),会走事件触发线程将对应的事件添加到对应的线程中(比如定时器操作,便把定时器事件添加到定时器线程),等异步事件有了结果,将其回调操作添加到事件队列,等待js引擎线程空闲时来处理
-
当对应的事件符合触发条件被触发时,该线程会把事件添加到待处理队列的队尾,等待JS引擎的处理
-
JS是单线程,所以这些待处理队列中的事件都得排队等待JS引擎处理
定时触发器线程
-
setInterval与setTimeout所在线程
-
浏览器定时计数器并不是由JavaScript引擎计数的(因为JavaScript引擎是单线程的,处于阻塞线程状态就会影响记计时的准确)
-
通过单独线程来计时并触发定时(计时完毕后,添加到事件触发线程的事件队列中,等待JS引擎空闲后执行),这个线程就是定时触发器线程,也叫定时器线程
-
W3C在HTML标准中规定,规定要求setTimeout中低于4ms的时间间隔算为4ms
异步http请求线程
-
在XMLHttpRequest在连接后是通过浏览器新开一个线程请求
-
当执行到一个http异步请求时,就把异步请求事件添加到异步请求线程,等收到响应(准确来说应该是http状态变化),再把回调函数添加到事件队列,等待js引擎线程来执行
线程
-
CPU 调度的最小单位
-
进程里面可以包含多个进程
- 单线程操作
-
同一个进程中的线程可以共享进程中的资源
-
定时器
JS 为什么是单线程
- 如果是双线程,dom 同时操作 body 添加和删除时会产生混乱