Optimizing Vue Performance with Prop Stability | LaraChamp
Back to Blog 3 min read

Optimizing Vue Performance with Prop Stability

In Vue.js, the component will re-render whenever a child component’s props change. This simple concept leads us to a crucial best practice that can significantly enhance our app’s performance: prop s...

Gurpreet Kait

Gurpreet Kait

Author

Share:
Link copied to clipboard!

In Vue.js, the component will re-render whenever a child component’s props change. This simple concept leads us to a crucial best practice that can significantly enhance our app’s performance: prop stability.

http://localhost/storage/uploads/Single-Responsibility-Principle-In-PHP-1024x576.png alt="prop stability in vue application" class="wp-image-1236"/>

What is Prop Stability?

Prop stability means keeping the props passed to a component stable, so they don't change frequently. This helps to avoid unnecessary re-renders and enhances your app's performance.

Example: List Item Component

Imagine we have a ListItem component that receives id, message, and activeId as props. Here’s how it might look in the template:

<template>
  <div>
    <span v-if="id === activeId">➤</span> {{ message }}
  </div>
</template>

To help us see when the component updates, we can import onUpdated from Vue and log a message whenever the component re-renders:

import { onUpdated } from 'vue';

export default {
  props: {
    id: Number,
    message: String,
    activeId: Number
  },
  setup(props) {
    onUpdated(() => {
      console.log(`Updating ${props.id}`);
    });
  }
}

Setting Up the Parent Component

In the parent component, we create an array of messages, each with a unique id and message, and a ref to keep track of the active message:

import { ref } from 'vue';
import ListItem from './ListItem.vue';

export default {
  components: { ListItem },
  setup() {
    const messages = [
      { id: 0, message: 'Message 1' },
      { id: 1, message: 'Message 2' },
      { id: 2, message: 'Message 3' },
    ];
    const activeId = ref(0);

    const next = () => {
      activeId.value = (activeId.value + 1) % messages.length;
    };

    return { messages, activeId, next };
  }
}

In the template, we render the ListItem components and add a button to change the activeId:

<template>
  <ul>
    <ListItem
      v-for="item in messages"
      :key="item.id"
      :id="item.id"
      :message="item.message"
      :activeId="activeId"
    />
  </ul>
  <button @click="next">Next</button>
</template>

Identifying the Problem

When you click the button, you’ll notice that all ListItem components re-render. This happens because the activeId prop changes for every item, causing unnecessary re-renders.

Improving with Stable Props

To optimize this, we can change the ListItem component to use an isActive prop instead of activeId:

<template>
  <div>
    <span v-if="isActive">➤</span> {{ message }}
  </div>
</template>

In the parent component, we determine isActive by checking if the id matches activeId:

<template>
  <ul>
    <ListItem
      v-for="item in messages"
      :key="item.id"
      :id="item.id"
      :message="item.message"
      :isActive="item.id === activeId"
    />
  </ul>
  <button @click="next">Next</button>
</template>

With this change, only the active item and the previously active item re-render when activeId changes. This reduces the number of re-renders, improving performance, especially for large lists.

I hope this will help, Happy Coding!

Enjoyed this article?

Subscribe to get more Laravel tutorials and development tips like this one

No spam, ever. Unsubscribe at any time.

My Project

ScreenSense

A Loom alternative built for individuals. Record, share, and explain anything with simple screen recordings.

Try ScreenSense
Articles Tags