背景
每一个页面都有一个渲染主线程,会处理很多任务,比如:DOM、样式计算、布局等等。如此多的任务就需要一个消息队列来进行管理。这些任务的类型,就是我们通常所说的宏任务以及微任务。
两种任务的关系,以及他们和UI线程渲染的关系
其实宏任务以及微任务的概念在前端已经是很普及的了,相关文章链接。但是有以下几个问题一直困扰着我:
- 宏任务以及微任务的关系
- 这两种任务和GUI渲染线程的关系
所以研究总结如下关系:
宏任务和他所产生的微任务是绑定的,一个宏任务执行完成后,这个宏任务所产生的微任务,以及微任务产生的微任务全部执行完后。才会执行下一个宏任务。如果这些任务耗时不长,那么一帧16ms内,可以执行多个宏任务。
如果一个宏任务以及宏任务产生的微任务耗时过长,超过16ms,那么就会造成UI线程渲染阻塞。其中如果一个宏任务耗时过长,也会等待其所产生的微任务执行完成后再进行UI线程渲染页面。
为什么要分两种任务?
每一个任务的执行当中,有可能会产生新的任务,那么这些新的任务有两种插入消息队列的方式:
这也主要是宏任务和微任务的区别,在任务执行过程中:
- 产生的宏任务直接插入消息队列尾部依次执行。
- 产生的微任务直接插入当前任务的微任务队列中,在此任务执行完成后,直接执行此任务的微任务队列。
可以看出微任务的存在主要是保证任务执行的时效性,而宏任务就是正常的直接插入消息队列尾部。
总结
- 宏任务和微任务是绑定关系,宏任务执行完成后会执行它所产生的微任务。
- 一帧内 (大多是16ms) ,可执行多个宏任务以及他们的微任务。
- 如果宏任务以及微任务执行时间过长,那么会阻塞UI线程的工作,导致页面卡顿、掉帧。
- 宏任务产生的微任务直接插入当前宏任务的微任务队列,这么做是为了保证任务执行的时效性。
- 宏任务执行过程中产生的宏任务,会直接放入消息队列的尾部,依次执行,新任务的执行时效性也就无法保证。