任务执行的时空舞台:宏任务、微任务与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 操作,能够减少页面的卡顿和性能问题。

相关推荐
王哈哈^_^1 小时前
【数据集】【YOLO】【目标检测】交通事故识别数据集 8939 张,YOLO道路事故目标检测实战训练教程!
前端·人工智能·深度学习·yolo·目标检测·计算机视觉·pyqt
cs_dn_Jie1 小时前
钉钉 H5 微应用 手机端调试
前端·javascript·vue.js·vue·钉钉
开心工作室_kaic2 小时前
ssm068海鲜自助餐厅系统+vue(论文+源码)_kaic
前端·javascript·vue.js
有梦想的刺儿2 小时前
webWorker基本用法
前端·javascript·vue.js
cy玩具3 小时前
点击评论详情,跳到评论页面,携带对象参数写法:
前端
清灵xmf3 小时前
TypeScript 类型进阶指南
javascript·typescript·泛型·t·infer
小白学大数据3 小时前
JavaScript重定向对网络爬虫的影响及处理
开发语言·javascript·数据库·爬虫
qq_390161773 小时前
防抖函数--应用场景及示例
前端·javascript
334554324 小时前
element动态表头合并表格
开发语言·javascript·ecmascript
John.liu_Test4 小时前
js下载excel示例demo
前端·javascript·excel