宏任务和微任务

微任务到底是什么?

微任务就是一个需要异步执行的函数,执行时机是在主函数执行结束之后,当前宏任务结束之前。

微任务有什么用?

微任务可以在实时性和效率之间做一个有效的权衡。

基于微任务的技术有哪些?

MutationObserver、Promise 以及以 Promise 为基础开发出来的很多其他的技术。

宏任务有哪些?

凡是在主线程上执行的任务都是宏任务。包括:

  • 渲染事件(如解析 DOM、计算布局、绘制);

  • 用户交互事件(如鼠标点击、滚动页面、放大缩小等);

  • JavaScript 脚本执行事件;

  • 网络请求完成、文件读写完成事件。

WHATWG规范中是如何定义事件循环机制的?

先从多个消息队列中选出一个最老的任务,这个任务称为 oldestTask;

然后循环系统记录任务开始执行的时间,并把这个 oldestTask 设置为当前正在执行的任务;

当任务执行完成之后,删除当前正在执行的任务,并从对应的消息队列中删除掉这个oldestTask;

最后统计执行完成的时长等信息。

为什么宏任务难以满足对时间精度要求较高的任务?

因为页面的渲染事件、各种IO的完成事件、执行JavaScript脚本的事件、用户交互的事件等都随时有可能被添加到消息队列中,而且添加事件是由系统操作的,JavaScript代码不能准确掌控任务要添加到队列中的位置,控制不了任务在消息队列中的位置,所以很难控制开始执行任务的时间。setTimeout函数触发的回调函数都是宏任务,如图所示:一旦中间插入别的任务,就会影响后面任务的执行。

![image-20201028143424051](/Users/zhoupanpan/Library/Application Support/typora-user-images/image-20201028143424051.png)

微任务是如何产生的?给谁使用?

当JavaScript执行一段脚本时,V8会为其创建一个全局执行上下文,创建的同时,V8也会在内部创建一个微任务队列用来存放微任务。

微任务队列是给V8引擎内部使用的,无法通过JavaScript直接访问。

微任务如何产生?
  • 使用 MutationObserver 监控某个 DOM 节点,然后再通过 JavaScript 来修改这个节点,或者为这个节点添加、删除部分子节点,当 DOM 节点发生变化时,就会产生 DOM 变化记录的微任务

  • 使用 Promise,当调用 Promise.resolve() 或者 Promise.reject() 的时候,也会产生微任务

微任务队列何时被执行?

在当前宏任务中的 JavaScript 快执行完成时,也就在 JavaScript 引擎准备退出全局执行上下文并清空调用栈的时候,JavaScript 引擎会检查全局执行上下文中的微任务队列,然后按照顺序执行队列中的微任务。WHATWG 把执行微任务的时间点称为检查点。

关于微任务的结论有哪些?
  • 微任务和宏任务是绑定的,每个宏任务在执行时,会创建自己的微任务队列。
  • 微任务的执行时长会影响到当前宏任务的执行时长。因此写代码时要注意控制微任务的执行时长
  • 在一个宏任务中,分别创建一个用于回调的宏任务和微任务,无论什么情况下,微任务都早于宏任务执行
监听DOM变化技术方案的演化史是怎样的?
  • 轮询检测

方式:使用setTimeout和setinterval来定时检测DOM是否有改变

问题:1、如果时间间隔设置过长,DOM变化响应不够及时;2、果果时间间隔设置过短,会浪费很多无用的工作量去检查DOM,会让页面变得低效。

  • Mutation Even

方式:采用了观察者的设计模式,当DOM有变动就会立刻触发相应的事件,这种方式属于同步回调。

优点:解决了实时性的问题。因为 DOM 一旦发生变化,就会立即调用JavaScript 接口

缺点:但也正是这种实时性引发了严重的性能问题,导致动画卡顿等。

  • MutationObserver

1、如何缓解性能问题?

将响应函数改成异步调用,等多次DOM变化后,一次触发异步调用,而非每次调用。并且使用一个数据结构来记录期间所有的DOM变化,以此减少对性能的影响。

2、如何保持消息通知的及时性?

通过微任务。每次DOM节点发生变化的时候,渲染引擎将变化记录封装成微任务,并将微任务添加进当前的微任务队列中。这样当执行到检查点的时候,V8引擎就会按照顺序执行微任务了。

综上所述: MutationObserver 采用了“异步 + 微任务”的策略。

通过异步操作解决了同步操作的性能问题

通过微任务解决了实时性的问题

posted @ 2020-10-28 15:06  小蜗蜗蜗牛^o^  阅读(212)  评论(0编辑  收藏  举报