Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to determine what causes components to rerender

I am having an issue where when I change a component in my app, many unrelated components seem to be rerendering too. When I use the Vue performance timings config, I see something like (all in the span of about 200ms)

Vue Performance screenshot

I am trying to figure out what causes these components to rerender. I saw a tip about how to tell the cause of a rerender, but when I put this snippet* in all the rerendering components, I don’t get anything logged to the console.

So, how can I find what is causing all these components to rerender?

*The code I actually put looks like

public mounted() {
    let oldData = JSON.parse(JSON.stringify(this.$data));
    this.$watch(() => this.$data, (newData) => {
      console.log(diff(oldData, newData));
      oldData = JSON.parse(JSON.stringify(newData));
    }, {
      deep: true,
    });
  }
like image 454
Max Coplan Avatar asked Oct 18 '25 13:10

Max Coplan


2 Answers

Using the F12 dev tools in Chrome, you can track down what is triggering your component to re-render. Add an updated hook to your component as below (using Options API):

updated() {
    if (!this.updateCnt)
        this.updateCnt = 1;
           
    if (this.updateCnt > 1) // set to desired
        debugger;

    console.log(`Updated ${this.updateCnt++} times`);
}

Or with Composition API:

let updateCnt = 0; 

onUpdated(() => {   
    if (updateCnt > 1) // set to desired
        debugger;   
    
    console.log(`Updated ${updateCnt++} times`); 
});

Refresh your page in Chrome with F12 tools open and wait for breakpoint to be hit. In the Sources tab, you will see the call stack on the right, with your updated() function as the current stack frame. Look back up the call stack and eventually you should see the code that caused the update to trigger. In my case, it was reactiveSetter() in the vue runtime, which was triggered by me setting a property in a parent component.

The code you have above will only trigger if a component's own state changes, not a parent.

like image 168
LMK Avatar answered Oct 21 '25 07:10

LMK


Using Vue 3's renderTriggered lifecycle event, you can see which reactive dependency triggered the component's render.

  renderTriggered({ key, target, type }) {
    console.log(`Render triggered on component '${this.name}'`, { key, target, type });
  }
like image 37
Zymotik Avatar answered Oct 21 '25 08:10

Zymotik