Skip to content
TOC

渲染进程很繁忙

渲染进程的主线程需要处理各种各样的任务,JS脚本,DOM渲染,布局,CSS计算,事件等等,V8引擎也是在主线程上运行的。

渲染进程里面除了主线程,还有IO线程,负责和其他线程进行IPC通信,还有一些辅助线程,比如DOM预解析线程,垃圾回收线程等。

消息队列+事件循环来帮忙

image.png

  • 添加一个消息队列;

  • IO 线程中产生的新任务添加进消息队列尾部;

  • 渲染主线程会循环地从消息队列头部中读取任务,执行任务。

如果是其他进程发过来消息,那么渲染进程专门有一个 IO 线程用来接收其他进程传进来的消息,接收到消息之后,会将这些消息组装成任务发送给渲染主线程,然后加入到消息队列中等待执行。

主线程退出

当所有任务执行完成后,主线程如何退出?

Chrome 是这样解决的,确定要退出当前页面时,页面主线程会设置一个退出标志的变量,在每次执行完一个任务时,判断是否有设置退出标志。(相当于立Flag)

单线程的缺点

1、如何处理高优先级任务

通常我们把消息队列中的任务称为宏任务,每个宏任务中都包含了一个微任务队列,在执行宏任务的过程中,如果有类似 DOM 变化需要及时响应的高优先级任务,那么就会将该变化添加到微任务队列中,这样就不会影响到当前宏任务的继续执行,因此也就解决了执行效率的问题。

等当前宏任务中的主要功能都直接完成之后,这时候,渲染引擎并不着急去执行下一个宏任务,而是看当前宏任务中的微任务队列中是否有微任务,如果有则执行当前宏任务中的微任务,因为类似 DOM 变化的事件都保存在这些微任务队列中,这样也就解决了实时性问题。

2、如何解决单个任务执行过长

如果有个 JavaScript 任务因执行时间过久,占用了动画单帧的时间,这样会给用户制造了卡顿的感觉,这当然是极不好的用户体验。针对这种情况,JavaScript 可以通过回调功能来规避这种问题,也就是让要执行的 JavaScript 任务滞后执行。

Released under the CC BY-NC-ND 3.0