SoFunction
Updated on 2025-04-12

Analysis of nextTick's principle in Vue

NextTick principle in Vue

1. Why nextTick is needed

Vue adoptsAsynchronous rendering mechanism,When responsive data changes, Vue does not update the DOM immediately, but puts these changes into aqueueand inSame event loopMerge the same modifications in (Event Loop) and finally perform batch updates.

The purpose of this isImprove performance and avoid unnecessary repeated rendering

For example:

<template>
  <div>{{ msg }}</div>
</template>

<script>
export default {
  data() {
    return {
      msg: "Hello"
    };
  },
  mounted() {
     = "Vue";
    (("div").innerText); // Still "Hello"    this.$nextTick(() => {
      (("div").innerText); // It's now "Vue"    });
  }
};
</script>

WhyOr "Hello"?

Because Vue is = "Vue"hourDOM will not be updated immediately, but wait until this round of event loop is over before updating. Therefore, we neednextTickto ensure that the updated DOM is obtained.

2. The principle of nextTick

Vue'snextTickEssentially oneAsynchronous Task Scheduler, it will be in the currentExecute callback after the DOM task is completed. Its internal principles mainly depend onMicrotasks and Macrotasks

2.1 Task Queue

Vue maintains an internalCallback queue(callback queue), whennextTickWhen called, it will callback functionPush into the queue, and then wait for Vue to perform DOM updates, and then execute these callbacks in turn.

2.2 Task Scheduling Strategy

nextTickuseElegant downgradeThe strategy to choose the best asynchronous method in different environments:

  1. Promise(Microtask)(Preferred, supported by modern browsers)
  2. MutationObserver(Microtask)(ComparesetTimeoutFaster)
  3. setImmediate(Macrotask)(IE only supports it)
  4. setTimeout(Macrotask)(The final bottom-up plan)

Code implementation:

function nextTick(callback) {
  const p = ();
  (callback);
}

In Vue 3:

let callbacks = [];
let pending = false;

function flushCallbacks() {
  pending = false;
  const copies = (0);
   = 0;
  for (let cb of copies) {
    cb();
  }
}

export function nextTick(cb) {
  (cb);
  if (!pending) {
    pending = true;
    ().then(flushCallbacks);
  }
}

Process analysis:

  1. Each callnextTick(cb),WillcbPut incallbacksIn queue.
  2. if onlypending === false, startMicrotasks ()
  3. Microtask executionflushCallbacks, call it in turncallbacksAll callbacks in the queue.

3. The difference between nextTick in Vue 2 and Vue 3

3.1 nextTick for Vue 2

In Vue 2,nextTickMain dependencies:

  • Microtask(, MutationObserver)
  • Macrotask(setImmediate, setTimeout)
  • Maintained oneAsynchronous task queue, used for batch executionnextTickCallback.

3.2 nextTick for Vue 3

Vue 3 main optimizations:

  • Use onlyPromiseAs a microtask (no longer using MutationObserver).
  • More efficientAsynchronous queue processing mechanism

Vue 3nextTick

const resolvedPromise = ();
export function nextTick(fn) {
  return fn ? (fn) : resolvedPromise;
}

Optimization point

  • Use directly().then(fn), avoiding Vue 2's complex callback queue management.
  • If not passed infn, then returns a Promise, supportedawait this.$nextTick()

4. NextTick usage scenarios

4.1 Perform an action after the DOM is updated

<template>
  <div ref="box">{{ message }}</div>
</template>

<script>
export default {
  data() {
    return { message: "Hello" };
  },
  methods: {
    updateMessage() {
       = "Vue";
      this.$nextTick(() => {
        (this.$); // "Vue"
      });
    }
  }
};
</script>

4.2 Wait for DOM update in watch

watch(() =&gt; , async (newVal) =&gt; {
  await nextTick();
  (("#counter").innerText); // Make sure the DOM is updated});

4.3 Use in Vue 3 setup

import { nextTick, ref } from "vue";

setup() {
  const message = ref("Hello");
  
  const updateMessage = async () => {
     = "Vue";
    await nextTick();
    (("#msg").innerText);
  };

  return { message, updateMessage };
}

Summarize

  • nextTickIt's one provided by VueAsynchronous task scheduling method, used to execute callbacks after DOM updates.
  • Vue adoptsAsynchronous batch updatemechanism,nextTickEnsureGet the latest DOM after data changes
  • Vue internally adoptedPromise (Microtask) priority, downgraded toMutationObserver / setTimeoutAs a backup plan.
  • Vue 3 has been further optimizednextTick, reduces unnecessary complexity and improves performance.

You can simply understand it as:

Vue will not update the DOM immediately after modifying the data, butBatch merge modificationand on the next timeUpdate the DOM at the end of the event loopnextTickLet you wait until the DOM update is completed before performing the operation.

The above is personal experience. I hope you can give you a reference and I hope you can support me more.