Async对DOM操作是否有用?滚动/鼠标监听异步调用的性能与并行问题
嘿,这个问题问到点子上了!很多人刚接触async/await的时候都会有类似的疑惑,咱们一点点拆解清楚~
首先直接给你结论:第一段的async函数不会更快,甚至可能有一丢丢可以忽略的额外开销;而且如果不对异步方法用await,它们也不会自动并行运行——得看你的方法本身是同步还是异步,以及调用方式。
1. 先看你那两段代码的实际执行逻辑
你代码里的method1()和method2()都是同步的DOM操作(比如修改元素样式、增删节点这类,浏览器的DOM API全是同步的),所以:
- 普通函数版本:先同步跑完
method1的所有DOM操作,再同步跑method2的,整个函数结束后直接返回undefined。 - async函数版本:依然会同步执行
method1和method2——因为没有await关键字触发暂停,函数体里的代码会从头到尾同步跑完,只是最后会返回一个状态为resolved的Promise对象。
两者的核心执行流程完全一致,DOM操作的顺序和耗时没有任何区别。反而async函数因为要创建和返回Promise,会多一点点性能成本(虽然几乎感受不到)。
2. 回到你开头的场景:scroll/mousemove事件里异步调用函数有用吗?
你提到浏览器的scroll或mousemove事件里,要操作多个元素,异步调用这些函数是否有益?
这里的关键是:DOM操作本身是同步的,你没法通过async/await让它们变成异步执行——因为浏览器的DOM API就是同步设计的。如果你的method1和method2里有大量的计算逻辑(不是直接操作DOM),那可以把这些计算放到setTimeout或者requestIdleCallback里,或者用Promise封装后并行执行,这样能避免阻塞事件循环,防止页面卡顿。
但如果只是纯DOM操作,异步调用不仅不会提升性能,反而可能因为事件循环的调度,导致DOM更新延迟,影响用户体验。
3. 什么时候不await会让异步方法并行?
假设你的method1和method2是异步函数(返回Promise),比如里面有网络请求或者定时器这类异步逻辑:
async function method1() { await fetch('/get/data1'); // 后续操作 } async function method2() { await fetch('/get/data2'); // 后续操作 }
这时候:
- 如果写成:
那么async function hello() { method1(); method2(); }method1和method2会被依次调用,它们内部的异步操作(比如这两个fetch请求)会并行执行,但hello函数不会等它们完成,直接返回一个resolved的Promise。 - 如果想让
hello等待两个异步操作都完成再继续,就得用Promise.all:
这样两个异步任务就会并行执行,async function hello() { await Promise.all([method1(), method2()]); }hello会等它们都结束才往下走。
但回到你的场景,DOM操作都是同步的,所以这种并行对你的情况完全不适用。
最后总结一下
- 你的两段代码执行效率几乎没差别,async版本不会更快;
- 没有await的async函数里,同步方法依然是同步顺序执行,异步方法会被调用但函数不会等它们完成,是否并行要看方法内部的异步逻辑;
- 在scroll、mousemove这类高频事件里,纯DOM操作没必要异步调用,反而要注意别堆太多同步操作阻塞事件循环——如果有大量计算,拆分到浏览器空闲时段执行会更合适。
内容的提问来源于stack exchange,提问作者williamsi

