当前位置: 首页 > news >正文

宏任务与微任务和Dom渲染的关系

测试网站1
测试网站2

在 JavaScript 的运行机制中,宏任务(Macrotask)、微任务(Microtask)以及 DOM 渲染之间的关系是理解异步编程和页面性能优化的关键。以下是对它们之间关系的详细解释:

一、宏任务(Macrotask)

  • 定义
    • 宏任务是 JavaScript 中执行时间较长的任务,通常包括:
      • 主任务(Main Task):这是 JavaScript 执行栈中的同步代码。
      • setTimeout/setInterval:这些函数设置的回调函数会在指定的延迟时间后被加入到宏任务队列中。
      • I/O 操作:如文件读写、网络请求等。
      • UI 渲染:浏览器的 DOM 渲染操作通常被视为宏任务的一部分。
  • 执行顺序
    • 宏任务的执行顺序是按照它们被加入到宏任务队列的顺序来执行的。例如,setTimeout 的回调函数会在指定的延迟时间后被加入到宏任务队列,然后按照队列顺序依次执行。

二、微任务(Microtask)

  • 定义
    • 微任务是 JavaScript 中执行时间较短的任务,通常包括:
      • Promise 的回调函数:当 Promise 的状态改变时(如从 pending 变为 fulfilled 或 rejected),对应的回调函数会被加入到微任务队列中。
      • MutationObserver:用于监听 DOM 树的变化。
      • process.nextTick(Node.js 环境):在 Node.js 中,process.nextTick 的回调函数会在当前事件循环阶段结束后立即执行。
  • 执行顺序
    • 微任务的执行顺序是在当前宏任务执行完成后,立即执行微任务队列中的所有任务。这意味着在每次宏任务执行完成后,都会清空微任务队列。例如,如果在一个宏任务中创建了多个 Promise,这些 Promise 的回调函数会在当前宏任务结束后立即执行。

三、DOM 渲染

  • 定义
    • DOM 渲染是浏览器将 DOM 树转换为可视页面的过程。这个过程包括布局(Layout)、绘制(Painting)和合成(Compositing)等步骤。
  • 执行顺序
    • DOM 渲染通常是在宏任务执行过程中触发的。当 JavaScript 执行栈中的同步代码执行完毕后,浏览器会检查是否有 DOM 更新需要渲染。如果有,浏览器会执行渲染操作。

四、宏任务、微任务和 DOM 渲染的关系

  1. 宏任务与 DOM 渲染

    • 宏任务的执行可能会触发 DOM 更新。例如,当你在 JavaScript 中修改了 DOM 元素的样式或内容时,浏览器会在当前宏任务执行完毕后进行 DOM 渲染。
    • 如果一个宏任务中包含多个 DOM 更新操作,浏览器会在宏任务执行完毕后一次性进行渲染,以避免频繁的重绘和重排,从而提高性能。
    • 例如:
      document.getElementById('myDiv').style.width = '100px';
      document.getElementById('myDiv').style.height = '100px';
      
      在这个例子中,两个 DOM 更新操作会在同一个宏任务中执行,浏览器会在宏任务结束后进行一次渲染。
  2. 微任务与 DOM 渲染

    • 微任务的执行不会直接触发 DOM 渲染。微任务会在当前宏任务执行完毕后立即执行,但不会中断宏任务的执行来触发渲染。
    • 微任务通常用于处理一些需要在 DOM 渲染之前完成的操作,例如更新状态、处理 Promise 的结果等。
    • 例如:
      document.getElementById('myDiv').style.width = '100px';
      Promise.resolve().then(() => {document.getElementById('myDiv').style.height = '100px';
      });
      
      在这个例子中,Promise.resolve().then() 创建了一个微任务。浏览器会在当前宏任务执行完毕后执行微任务,但不会在微任务执行过程中触发 DOM 渲染。只有在微任务队列清空后,浏览器才会进行 DOM 渲染。
  3. 宏任务、微任务和 DOM 渲染的顺序

    • 事件循环的执行顺序是:当前宏任务 → 微任务队列 → 渲染 → 下一个宏任务。
    • 例如:
      console.log('1');
      setTimeout(() => {console.log('2');
      }, 0);
      Promise.resolve().then(() => {console.log('3');
      });
      console.log('4');
      
      输出结果为:
      1
      4
      3
      2
      
      解释:
      • console.log('1')console.log('4') 是同步代码,属于当前宏任务。
      • Promise.resolve().then() 创建了一个微任务,会在当前宏任务结束后立即执行,输出 3
      • setTimeout 的回调函数会在下一个宏任务中执行,输出 2
      • 在当前宏任务结束后,浏览器会执行微任务队列中的任务,然后进行 DOM 渲染(如果有 DOM 更新的话)。

总结

  • 宏任务:执行时间较长,可能触发 DOM 渲染。
  • 微任务:执行时间较短,不会直接触发 DOM 渲染,但会在宏任务结束后立即执行。
  • DOM 渲染:通常在宏任务执行完毕后进行,不会在微任务执行过程中触发。

理解宏任务、微任务和 DOM 渲染之间的关系对于编写高效的 JavaScript 代码和优化页面性能非常重要。

http://www.xdnf.cn/news/1074565.html

相关文章:

  • 左神算法之螺旋打印
  • Redis Cluster Gossip 协议
  • 在Linux系统中部署Java项目
  • 设计模式之装饰者模式
  • 2.安装Docker
  • 怎样学习STM32
  • 暴力风扇方案介绍
  • HarmonyOS实战:自定义表情键盘
  • FPGA实现CameraLink视频解码,基于Xilinx ISERDES2原语,提供4套工程源码和技术支持
  • llama.cpp学习笔记:后端加载
  • 图书管理系统练习项目源码-前后端分离-使用node.js来做后端开发
  • Conda 环境配置之 -- Mamba安装(causal-conv1d、mamba_ssm 最简单配置方法)-- 不需要重新配置CDUA
  • 领域驱动设计(DDD)【26】之CQRS模式初探
  • AlpineLinux安装部署elasticsearch
  • Kafka4.0初体验
  • Python爬虫:Requests与Beautiful Soup库详解
  • 重写(Override)与重载(Overload)深度解析
  • 【C++】C++中的友元函数和友元类
  • 71. 简化路径 —day94
  • Bugku——WEB篇(持续更新ing)
  • documents4j导出pdf
  • Ubuntu服务器(公网)- Ubuntu客户端(内网)的FRP内网穿透配置教程
  • 数据结构 哈希表、栈的应用与链式队列 6.29 (尾)
  • 现代 JavaScript (ES6+) 入门到实战(八):总结与展望 - 成为一名现代前端开发者
  • day46/60
  • H3C-路由器交换机-中继
  • 计算机组成原理与体系结构-实验一 进位加法器(Proteus 8.15)
  • 5 c++核心——文件操作
  • MySQL技巧
  • 如何优化RK3588集群的性能?支持12个RK3588云手机阵列