zoukankan      html  css  js  c++  java
  • 宏任务和微任务

    微任务到底是什么?

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

    微任务有什么用?

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

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

    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 采用了“异步 + 微任务”的策略。

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

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

  • 相关阅读:
    Python高级特性-迭代
    Python列表生成式测试
    Python函数基础学习(定义、函数参数、递归函数)
    Html介绍,认识head标签
    Html介绍,认识html文件基本结构
    Html介绍,标签的语法
    Html介绍,认识html标签
    Html介绍,了解html与css关系
    Html介绍,如何用代码展示我制作的第一个网页?
    C++走向远洋——38(用对象数组操作长方柱类)
  • 原文地址:https://www.cnblogs.com/zpsakura/p/13891201.html
Copyright © 2011-2022 走看看