写在前面: 看面经的一定少不了看Js的eventLoop,只要能看懂,给出一串代码,想必都能答对代码的执行顺序。但是在我看浏览器渲染进程的时候,我发现关于对事件循环的理解,好像可以拔高一个角度来看。
言归正传,浏览器渲染进程的线程有哪些?
- GUI渲染线程
- Js引擎线程
- 事件触发线程
- 定时器触发线程
- 异步http线程
下面详细说说。
1.GUI渲染线程
负责渲染浏览器页面,解析HTML、CSS、构建DOM树、构建CSSOM树、render树和绘制页面。当页面发生重绘和重排时,GUI渲染线程会负责执行。
2.Js引擎线程
即JS内核,负责解析和运行JS脚本,JS线程是单线程。JS线程一直等着任务队列中任务的到来。
注意: GUI线程和JS线程是互斥的,即GUI线程和JS线程不能同时执行。当JS线程执行时GUI线程会暂停,GUI更新会被保存在一个队列中,当JS线程执行完毕后再执行。
3.事件触发线程
注意,事件触发线程属于浏览器线程而不是JS引擎,用来控制事件循环。当JS引擎执行如setTimeOut之类异步代码时,事件触发线程会把事件添加到待处理队列的尾部,等待JS引擎的处理。
4.定时器触发线程
我们熟悉的定时器是在定时器触发线程计时而不是在JS引擎线程中计时。JS是单线程,如果处于阻塞状态就会影响计时的准确性,所以单独开个线程来计时并触发定时器。计时结束后,将事件添加到事件队列等待JS引擎处理。定时器中的任务在设定的时间点不一定执行,但是一定是按时添加到事件队列中。
5.异步http线程
XMLHttpRequest建立连接后通过浏览器新开一个异步http线程,当状态变化时,异步线程就产生变更事件,将回调函数添加到事件队列中,等待JS引擎处理。
总结: 看到这里,是不是明白了JS的事件队列里是怎么被添加事件的?GUI渲染线程和Js引擎线程负责渲染页面,后面三个线程负责管理调度,往JS的事件队列中添加待处理事件。
个人思考: 任何一种机制都不是凭空出现,起初都是基于达到某种目的来设定和完善的,设计的人是制定者,使用和研究的人如果能站在设计者的角度去研究,那是不是就会很容易达成共鸣?其次,类似浏览器渲染进程如此清晰的管理机制,是不是也可以应用到我们日常的复杂项目开发中呢?