Inferno: [Performance] Add lots of items to the DOM

Created on 14 Dec 2016  路  7Comments  路  Source: infernojs/inferno

Hi,

I'm looking for some informations on how to add lots of items to the DOM.

Here's a jsfiddle example.

Note that in this example I'm using a while loop with 2000 items. It makes the browser freeze.
If I use an interval instead, everything works fine.

Now, in my real use case I'm getting about 6600 items through websockets. When an item is received it's added to the view. I'm seeing the same behavior as with my while loop above, hence the browser freeze until everything is done (too fast? not comparable to setInterval(x, 0)?).

On the other hand, if I use vanillaJS, I've no problem adding my elements to the DOM, for example:

const container = document.getElementById('app')
let list = document.createElement('ul')
container.appendChild(list)

//Get some data from a websocket
fetch()
//reactive stream subscribe (most.js)
.observe((e) => {
    let element = document.createElement('li')
    element.innerText = e.text
    list.appendChild(element)
})
.then(() => {
    console.log(list.children.length) // 6600
})

As Inferno is powerful (which you can see through the many benchmarks) I know I'm doing something wrong. Could you please tell me how I can improve the above jsfiddle to be performant enough?

Thanks!

question

All 7 comments

@soyuka Inferno's setState when used in your case will be sync on each call, thus causing it to do a diff each time. You can however force the setState to by async by passing in a callback as the 2nd parameter. In your case, you don't really need a callback, so you can pass in a NO OP function and get much better performance. As shown:

https://jsfiddle.net/r9g44v7m/

Hi @soyuka,

In general, you want to avoid Component whenever you can because functional components are faster (as opposed to "stateful components").

In your case, since you're just passing static/dummy data, there's no need to use or set a state here. Ergo, I remade your fiddle with functional components.

PS: Another way to think of it is that functional components are one-directional; they do not need to send new data or, aside from the first time, _remember_ what they were told to do. (The exception here is that functional components can "send" data if a prop contained a parent's method... technicalities.)

Here's the fiddle: https://jsfiddle.net/lukeed/htegwjeh/

Another major difference is that you were setting state 2000 times. Each call of setState re-renders the tree & all its children. So, that means that by 5th iteration, you were re-rendering 1->4 and on the 1000th iteration, you were re-rendering 1 -> 999 too.

I can provide a 'stateful' example too if you'd like.

Hi, thanks for both of your answers!

It's kinda hard to find docs/examples about inferno, hope the website will be released soon!

I understand the functional vs stateful, didn't found any functional example though. Also, I must say I dislike JSX, so here's your fiddle with hyperscript:

https://jsfiddle.net/htegwjeh/1/

Though, how would you render the children in an asynchronous way? I don't think that the children arguments accepts a Stream/Observable nor a Promise?

@lukeed you are comparing one render vs 2000 renders, also using class in given scenario shouldn't make any noticeable difference because there is only 1 class constructed

I think point of 2000 renders here was to to simulate behavior with websockets

I created jsfiddle with functional components resulting same as bad performance as with classes.
https://jsfiddle.net/htegwjeh/2/
and now it cannot even be async anymore? (according to my knowledge).

There is no silver bullet to get best performance. It highly depends on usage and requirements

@Havunen thanks for the second example, interesting that indeed it cannot be async anymore (according to you knowledge).

@trueadm Thanks about the setState tip! Works great (even better then my poor vanillajs implementation)

The slowest uses the above vanillajs implementation:

inferno-rocks-2

Inferno (with a NOOP function to force async):

inferno-rocks

Note that every item from that list comes from a websocket request sent by the server.

I can publish the code if someone wants, for the readdir part it's available here.

@Havunen Correct. I learned something new after looking at @trueadm's answer 馃槃

Was this page helpful?
0 / 5 - 0 ratings

Related issues

devanp92 picture devanp92  路  20Comments

thepian picture thepian  路  20Comments

kurdin picture kurdin  路  28Comments

trueadm picture trueadm  路  25Comments

AlgoTrader picture AlgoTrader  路  54Comments