Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Vue.js, How to find what data changes cause a component to re-render?

Tags:

vue.js

vuejs2

In Vue.js, a component does re-render(update) when some data changes. Sometimes the re-render frequency is too often and i want to find out which data's change cause this re-render. How to find out the changed data causing the re-render?

like image 406
tomwang1013 Avatar asked May 29 '18 08:05

tomwang1013


People also ask

What triggers re-render in Vue?

The best way to force Vue to re-render a component is to set a :key on the component. When you need the component to be re-rendered, you just change the value of the key and Vue will re-render the component.

How do I watch data changes on Vue instance?

A Watcher in Vue. js is a special feature that allows one to watch a component and perform specified actions when the value of the component changes. It is a more generic way to observe and react to data changes in the Vue instance. Watchers are the most useful when used to perform asynchronous operations.

How do you prevent components from rendering after state change?

1. Memoization using useMemo() and UseCallback() Hooks. Memoization enables your code to re-render components only if there's a change in the props. With this technique, developers can avoid unnecessary renderings and reduce the computational load in applications.

How do you prevent components from Rerendering?

If you're using a React class component you can use the shouldComponentUpdate method or a React. PureComponent class extension to prevent a component from re-rendering.


2 Answers

Using deep-diff and a simple watcher, you can easily find the difference between a previous copy of your vm data.

new Vue({
  el: "#app",
  data: {
    counter: 0
  },
  mounted() {
    let oldData = JSON.parse(JSON.stringify(this.$data));
    this.$watch(vm => vm.$data, (newData) => {
      console.log(DeepDiff.diff(oldData, newData));
      oldData = JSON.parse(JSON.stringify(newData));
    }, {
      deep: true
    });
  },
  methods: {
    add: function() {
      this.counter++;
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/deep-diff@1/dist/deep-diff.min.js"></script>
<div id="app">
  <button @click="add"> +1 </button> {{ counter }}
</div>
like image 133
FitzFish Avatar answered Oct 24 '22 04:10

FitzFish


Further to above, and as noted in the comments the deep watcher will only work if the component's own data has changed. A more conclusive method is shown below (also posted to https://stackoverflow.com/a/69275418/960380)

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:

updated() {

            if (!this.updateCnt)
                this.updateCnt = 1;
           
            if (this.updateCnt > 1) { // set to desired
                debugger;
            }
            console.log(`Updated ${this.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.

like image 35
LMK Avatar answered Oct 24 '22 06:10

LMK