1

I'm using a component to render a dynamic table which has "many" rows. Sometimes I add new rows, sometimes I modify existing rows, but whenever I do any of that, Vue will re-render the entire table and that takes a considerable time, which I would like to avoid.

I'm using keys and stuff to accelerate the re-rendering process, but I still feel the process is inefficient: Vue will at least run through each row, checking whether it has changed or not.

<tr v-for="row in rows" :key="row['id']">....</tr>

I know the rows affected each time.

How can I tell Vue it should only bother with those when it re-renders?

I have considered to have two lists: the stationary one and the changing one, but I have no idea how I could do the <tr v-for="item in two_lists"/> such that Vue would actually ignore the first list when re-rendering.

OTOH, I also found this thread with an excellent explanation by NovaMage in the last reply. If I read that correctly, I would be better off if I made rows components and passed individual row data to them? Because initially I DIDN'T make them components precisely for performance reasons (instantiating thousands of components can't ever be too good for performance, right?)

Anyway, again: How can I tell Vue it should only bother with changed rows when it re-renders?

3
  • compute rows so its not "many" and use pagination and filtering. Less DOM faster rendering, better ux Commented May 19, 2021 at 9:16
  • What version of Vue are we talking about ? Commented May 19, 2021 at 10:46
  • @MichalLevý: 2.6.12 Commented May 19, 2021 at 12:02

1 Answer 1

1

Rendering granularity in Vue is always a component. Component's template is compiled into a render function. When re-render is needed, render function is executed as a whole unit. There are some optimizations the template compiler can do (like hoisting static content for example) and from what I know there are some significant improvements in Vue 3 in this field but I think the optimization of v-for loops is not one of them (ie. rendering only for some items in the loop and skip others)

So yes, creating a Row component might be a solution to optimize rendering performance for some operations at the cost of some memory and time needed for instantiating the components. Adding/removing items from array will probably still result in table component re-render, but unchanged Row components will not re-render even in this case (see demo below)

I do not know what "many" exactly means, but assuming only fraction of the rendered rows is visible on the screen at the time, the best optimization you can do (except of pagination mentioned in comments) is using some kind of "virtual scroll" component - for example vue-virtual-scroller

Vue.component("row", {
  props: ["data"],
  data() {
    return {};
  },
  template: `
  <tr>
    <td><button @click="$emit('update-row', data)">Update row</button></td>
    <td>{{ new Date() }}</td>
    <td>{{ data.id }}</td>
    <td>{{ data.text }}</td>        
  </tr>
`
});

const initialCount = 2
const vm = new Vue({
  el: '#app',
  data() {
    return {
      count: initialCount,
      rows: Array.from({
        length: initialCount
      }, (v, i) => ({
        id: i,
        text: `text - ${i}`
      }))
    }
  },
  methods: {
    addRow() {
      this.rows.push({
        id: this.count,
        text: `text - ${this.count} `
      })
      this.count++
    },
    updateRow(row) {
      row.text = row.text + 'U'
    }
  },  
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id="app">
  Table rendered: {{ new Date() }}
  <button @click="addRow">Add row</button>  
  <table>  
    <tr v-for="row in rows" is="row" :data="row" :key="row.id" @update-row="updateRow" />
  </table>
</div>

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.