浏览器是多线程的,但是JS
是单线程的。
GUI渲染线程
- 负责渲染浏览器界面,解析
HTML
,CSS
,构建DOM
树和Render
树,布局和绘制等。 - 当界面需要重绘
Repaint
或由于某种操作引发回流Reflow
时,该线程就会执行。 - 要注意的是
GUI
渲染线程与JS
引擎线程是互斥的,当JS
引擎执行时GUI
线程会被挂起(相当于被冻结了),GUI
更新会被保存在一个队列中等到JS
引擎空闲时立即被执行。
JS引擎线程
-
JS
引擎线程也称为JS
内核,负责处理Javascript
脚本程序。(例如V8
引擎) -
JS
引擎线程负责解析Javascript
脚本,运行代码。 -
JS
引擎一直等待着任务队列中任务的到来,然后加以处理,无论什么时候都只有一个JS
线程在运行JS
程序。 - 同样注意,
GUI
渲染线程与JS
引擎线程是互斥的,所以如果JS
执行的时间过长,这样就会造成页面的渲染不连贯,导致页面渲染加载阻塞。
事件触发线程
- 归属于浏览器而不是
JS
引擎,用来控制事件循环(可以理解成JS
引擎自己都忙不过来,需要浏览器另开线程协助)。 - 当
JS
引擎执行代码块,如鼠标点击,会将对应任务添加到事件线程中。 - 当对应的事件符合触发条件被触发时,该线程会把事件添加到待处理队列的队尾,等待
JS
引擎的处理。 - 注意,由于
JS
的单线程关系,所以这些待处理队列中的事件都得排队等待JS
引擎处理(当JS
引擎空闲时才会去执行)。
定时触发器线程
-
setInterval
与setTimeout
所在线程。 - 浏览器定时计数器并不是由
JavaScript
引擎计数的,(因为JavaScript
引擎是单线程的, 如果处于阻塞线程状态就会影响记计时的准确)。 - 因此通过单独线程来计时并触发定时(计时完毕后,添加到事件队列中,等待
JS
引擎空闲后执行)。 - 注意,
W3C
在HTML
标准中规定,规定要求setTimeout
中低于4ms
的时间间隔算为4ms
。
异步http请求线程
- 在
XMLHttpRequest
在连接后是通过浏览器新开一个线程请求。 - 将检测到状态变更时,如果设置有回调函数,异步线程就产生状态变更事件,将这个回调再放入事件队列中,再由
JavaScript
引擎执行。
网友评论