任务执行的时空舞台:宏任务、微任务与DOM变化监听的完美协奏曲

随着浏览器应用的不断发展,我们在处理任务的方式上也经历了一些变革。传统的消息队列机制在某些领域已经不能满足实时性和效率的需求,因此出现了微任务的概念,使我们能够更灵活地在实时性和效率之间取得平衡。

1.宏任务

在浏览器中,大部分任务都是在主线程上执行的,这包括了渲染事件、用户交互事件、JavaScript 脚本执行事件、网络请求完成、文件读写完成等。为了协调这些任务的执行,浏览器引入了消息队列和事件循环机制。渲染进程内部维护多个消息队列,如延迟队列、普通消息队列等。主线程通过一个 for 循环不断从这些任务队列中取出任务并执行。

消息队列中的任务被称为宏任务,其执行过程大致分为以下步骤:

  1. 先从消息队列中取出一个最老的任务,称为`oldestTask。
  2. 然后循环系统记录任务开始执行的时间,并把这个oldestTask设置为当前正在执行的任务。
  3. 当任务执行完成之后,删除当前正在执行的任务,并从对应的消息队列中删掉这个oldestTask
  4. 最后统计执行完成的时长等信息。

尽管宏任务是一种可靠的执行方式,但对于对时间精度有更高要求的场景,宏任务的粗时间颗粒度就显得不够灵活。

2.微任务

为了解决宏任务的时间颗粒度问题,引入了微任务的概念。微任务是一种需要异步执行的函数,其执行时机是在主函数执行结束之后、当前宏任务结束之前。 每个宏任务都会关联一个微任务队列 ,而在 JavaScript 执行脚本时,V8 引擎会在全局执行上下文中创建一个微任务队列。

微任务产生的时机和执行微任务的时机

微任务产生的时机

  1. 使用MutationObserver监控某个DOM节点,然后通过JavaScript来修改这个节点,或者为这个节点添加、删除子节点,当DOM节点发生变化时,就会产生DOM变化记录的微任务。
  2. 使用promise,当调用Promise.resolve()或者Promise.reject()的时候也会产生微任务。

执行微任务的时机

微任务的执行时机通常在当前宏任务中的 JavaScript 快执行完成时,这个时刻被称为微任务检查点 。在检查点时,JavaScript 引擎会检查全局执行上下文中的微任务队列,并按照顺序执行队列中的微任务。值得注意的是,如果在执行微任务的过程中产生了新的微任务,它将被添加到微任务队列中,并在当前宏任务中继续执行,而不会推迟到下个宏任务。

3.监听DOM变化方法的演变

Web开发中,监听DOM变化的方法经历了一些演变。以下是一些常用的监听 DOM 变化的方法及其演变:

1. 轮询(Polling):

早期的 DOM 监听方式是通过轮询检查 DOM 是否发生变化。通过定期检查 DOM 结构的变化,然后执行相应的操作。这种方法的缺点是效率低下,不够实时,同时可能会造成性能问题。

js 复制代码
setInterval(function () {
    // 检查 DOM 变化
    // 执行相应操作
}, 1000);  // 每秒轮询一次

2. 事件监听器:

随着浏览器的发展,引入了更为实时的事件监听器,允许开发者监听 DOM 元素的特定事件,从而实时获取变化。

js 复制代码
document.addEventListener('change', function (event) {
    // 处理 DOM 变化事件
});

3. MutationObserver:

MutationObserver 是一个现代的、高效的 API,用于异步监听DOM的变化。它能够捕获到DOM 树的变化,包括节点的增加、删除、属性的变化等。相对于事件监听器,MutationObserver 提供了更为灵活和强大的功能。

js 复制代码
// 创建一个 MutationObserver 实例
const observer = new MutationObserver(function (mutationsList, observer) {
    // 处理 DOM 变化
});

// 配置监听选项
const config = { attributes: true, childList: true, subtree: true };

// 开始监听
observer.observe(document.body, config);

MutationObserver 的优势在于它不会阻塞主线程,而是通过异步方式捕获 DOM 变化,因此更适用于大规模的、频繁的 DOM 操作。

4.性能优化建议

微任务的合理使用

在使用微任务时,需要谨慎并避免过度依赖微任务来处理任务。过多的微任务可能导致性能问题,因此应该合理权衡宏任务和微任务的使用,确保在不牺牲实时性的前提下提高效率。

utationObserver 的异步特性

开发者需要注意 MutationObserver 具有异步特性,不会阻塞主线程。这使得 MutationObserver 更适用于大规模、频繁的 DOM 操作,能够减少页面的卡顿和性能问题。

相关推荐
2401_8827275715 分钟前
低代码配置式组态软件-BY组态
前端·后端·物联网·低代码·前端框架
NoneCoder18 分钟前
CSS系列(36)-- Containment详解
前端·css
anyup_前端梦工厂29 分钟前
初始 ShellJS:一个 Node.js 命令行工具集合
前端·javascript·node.js
5hand33 分钟前
Element-ui的使用教程 基于HBuilder X
前端·javascript·vue.js·elementui
GDAL1 小时前
vue3入门教程:ref能否完全替代reactive?
前端·javascript·vue.js
六卿1 小时前
react防止页面崩溃
前端·react.js·前端框架
z千鑫1 小时前
【前端】详解前端三大主流框架:React、Vue与Angular的比较与选择
前端·vue.js·react.js
m0_748256142 小时前
前端 MYTED单篇TED词汇学习功能优化
前端·学习
小马哥编程3 小时前
Function.prototype和Object.prototype 的区别
javascript
小白学前端6663 小时前
React Router 深入指南:从入门到进阶
前端·react.js·react