Hammerbot
Hammerbot

Reputation: 16344

Rendering a lot of components

I am trying to make a small application with VueJS and I am having some performance issues.

I'm not sure that this is something I can do something for, but asking anyway.

My goal is to render a lot of components (more than 10,000 at the same moment). But the time it takes to Vue to render thoses components and update the dom is quite long.

Here I made a small JsFiddle so you can try on your side: https://jsfiddle.net/rt5cjbby/

At home, with a badass i7 processor, it takes 400ms to render. Which is, much more when you test with more components.

My question is: Is there any technique I could use to have better performances?

Is it possible to update the DOM every 100 components to be rendered? The client could see the first 100 components very quickly then the browser would continue to render....

Here is my example code if you don't want to open jsFiddle:

some_table = []

for (let i = 0; i < 2000; i++) {
    some_table.push({
    foo: 'bar'
  })
}

let someComponent = Vue.extend({
  template: '#some-component',
  props: ['input']
})

new Vue({
  el: '#app',
  data: {
    lines: some_table
  },
  components: {
    someComponent
  }
})

And my templates:

<div id="app">
  <div  v-for="line in lines">
    <some-component :input="line"></some-component>
  </div>
</div>

<template id="some-component">
  <div>
    {{ input.foo }}
  </div>
</template>

Of course, I could fill my table every 0.01s but I don't feel that this is the best solution.

PS: I accept responses like "[Angular|React] are better for your usecase because ...."

Thank you very much for your help/experiences/advices and have a nice day

Upvotes: 2

Views: 3185

Answers (1)

David L
David L

Reputation: 33833

If you are interested in only rendering the component's end result, you can easily achieve exceptional performance utilizing the render function.

Here is a complete working Fiddle of the following:

Template:

<div id="app"></div>

Javascript:

some_table = []

for (let i = 0; i < 10000; i++) {
  some_table.push({
    foo: 'bar'
  })
}

new Vue({
  el: '#app',
  data: {
    lines: some_table
  },
  render: function (createElement) {
    if (this.lines.length) {
      return createElement('div', this.lines.map(function (line) {
        return createElement('div', line.foo)
      }))
    } else {
      return createElement('p', 'No items found.')
    }
  }
})

setTimeout(() => {
  for (let i = 0; i < 10; i++) {
    some_table.unshift({
      foo: 'bar stool'
    })
  }
}, 2500)

In this example, 10,000 "cells" are rendered almost immediately (about 450ms while profiling on my machine). After a 2.5 second delay, an additional 10 new records are added as well, since the render function will respond to changes to the array. This allows you to make changes to the rendered state as needed by modifying the source array.

Note that you can still perform complex 2-way data binding via your own v-model implementations in render functions, although it is significantly harder to maintain.

Upvotes: 2

Related Questions