React: Why is react so slow rendering 900 items? (with jsfiddle)

Created on 26 Nov 2014  Â·  21Comments  Â·  Source: facebook/react

Hi guys,
I'm evaluating react.js (considering using it in some projects) but I'm having trouble rendering a simple list with 910 elements, since it takes almost 4 seconds.
This is not a complex markup (just a couple of div tags), actually it's an existing app simplification.
I tried this using just underscore.js and it took 500ms!!

Jsfiddle:

What am I doing wrong?

Cheers,
Vasco Pessanha

Question

Most helpful comment

I confirm that react is VERY slow when there are many elements. It is drastically slow. It has nothing to do between its name and real-life usage.

Hi, we’d love to help you but this is very vague. How many elements? If you render more than a thousand elements in a page, you probably can’t show them all at once anyway. In this case it is better to used virtualized lists so that you can render as many items as you need and stay performant. You can also use something like MobX for automatic granular subscriptions if you’re hitting performance limits with thousands of items with traditional React data flow.

That said, it is equally likely that React can be fast in your case if you:

This is a good guide to optimizing performance of React apps. Please check it out if you’re interested!

It is definitely not reactive.

“Reactive” refers to the fact that when you update the state, the DOM is updated automatically, “reacting” to the state change. It doesn’t mean React claims to be the fastest library possible. However it is definitely used very widely at Facebook, including React Native where performance is very important, so it enjoys a ton of real-world usage.

All 21 comments

Please attempt to use a newer stable version of React, jsfiddle only seems to offer 0.9.0. But jsbin offers the newest stable version.

Hi aackerman,
I also tried with the newest "0.12.0" version (actually it's the jsfiddle without jsx)

React does more than just writing the html, so it will never be the fastest at that. But I guess most of the slowness you see comes from jsfiddle. Have a look at the time the render takes. Just surround the render with time taking:

console.log('Start render');
var t0 = Date.now();
React.renderComponent(React.createElement(CustomerListPage, {customers: RAW_DATA}), document.body);
var t1 = Date.now();
console.log('Render took', t1-t0, 'ms');

JSXTransformer (the script, used by JSFiddle) is only intended for basic development needs, it's slow (at startup) and generally a very bad idea. Pre-processed JSX has no run-time overhead.

Also, you're using the development version, which offers good error messages and other checks while compromising on perf.

Thanks for your answers guys..
I've tested this same example using the production version, and one of the fiddles of my post is using js (not jsx) so I really don't think those are the issues..

Cheers

I think the point here is: if we use a simpler library like Underscore templates that generates the markup string in memory and then performs a single DOM update - in this case, something like "document.body.innerHtml()", it is much faster than React... why?

Does anyone have additional feedback about this? I'm also evaluating React and I would like to know if it scales well for a large number of DOM elements. Are there any workarounds to speed up the first render for these scenarios?

@ricardosoeiro Frameworks always have overhead, you'll have to compare it non-naively to some other suitable framework for it to make any sense. My general guideline is that if you have so many DOM elements that first render is visibly slow, you're doing it wrong... faster performance is not the solution, it's a band-aid. Add content dynamically as it is scrolled into view, etc, that way it scales properly.

PS. Also React will become faster and faster over time.

Speed to first render is important, but if it's so highly important to your project, it could be better to render server-side, that may not be possible or worth the effort I imagine.

But, I agree about adding content dynamically, it would be possible for you to render the first 50 items on the first render, probably far more items than a person could see on the page without scrolling, and then the rest on the second render, milliseconds later. It requires some extra writing effort upfront, but hopefully it's a one time effort, and provides a shorter perceived load time.

The answer to your evaluation of React really depends on the trade-offs you want to make. I'm willing to accept lower render performance for the simplicity and low mental overhead that React provides.

Your JSX-less example is consistently around 800ms on Chrome on my computer. Perhaps JSFiddle is slow because eval prevents JIT optimizations?

Here is my test case (standalone HTML). (I'm just really hoping this is not _actual_ customer data with emails, telephones and addresses that you're posting).

I think the point here is: if we use a simpler library like Underscore templates that generates the markup string in memory and then performs a single DOM update

AFAIK this is precisely what React is doing on first render.

This is a good topic for a mailing list (sorry, I should have said that sooner). As mentioned, there appear to be some discrepencies on what is causing performance issues for you. React does more than simple string templating so yes, there will likely be additional overhead as React sets up and maintains references and other stores and caches so that updates can be fast.

I confirm that react is VERY slow when there are many elements. It is drastically slow. It has nothing to do between its name and real-life usage. It is definitely not reactive.

I confirm that react is VERY slow when there are many elements. It is drastically slow. It has nothing to do between its name and real-life usage.

Hi, we’d love to help you but this is very vague. How many elements? If you render more than a thousand elements in a page, you probably can’t show them all at once anyway. In this case it is better to used virtualized lists so that you can render as many items as you need and stay performant. You can also use something like MobX for automatic granular subscriptions if you’re hitting performance limits with thousands of items with traditional React data flow.

That said, it is equally likely that React can be fast in your case if you:

This is a good guide to optimizing performance of React apps. Please check it out if you’re interested!

It is definitely not reactive.

“Reactive” refers to the fact that when you update the state, the DOM is updated automatically, “reacting” to the state change. It doesn’t mean React claims to be the fastest library possible. However it is definitely used very widely at Facebook, including React Native where performance is very important, so it enjoys a ton of real-world usage.

Agree, I've been using virtualized lists and reducing the number of DOM
elements in the lists and you can get performant lists!

Vasco Pessanha
Senior Software Engineer
OutSystems

www.outsystems.com

On Tue, May 17, 2016 at 12:27 PM, Dan Abramov [email protected]
wrote:

I confirm that react is VERY slow when there are many elements. It is
drastically slow. It has nothing to do between its name and real-life usage.

Hi, we’d love to help you but this is very vague. How many elements? If
you render more than a thousand elements in a page, you probably can’t show
them all at once anyway. In this case it is better to used virtualized
lists https://bvaughn.github.io/react-virtualized/ so that you can
render as many items as you need and stay performant. You can also use
something like MobX https://github.com/mobxjs/mobx for automatic
granular subscriptions if you’re hitting performance limits with thousands
of items with traditional React data flow.

That said, it is equally likely that React can be fast in your case if you:

This is a good guide
http://benchling.engineering/performance-engineering-with-react/ to
optimizing performance of React apps. Please check it out if you’re
interested!

It is definitely not reactive.

“Reactive” refers to the fact that when you update the state, the DOM is
updated automatically, “reacting” to the state change. It doesn’t mean
React claims to be the fastest library possible. However it is definitely
used very widely at Facebook, including React Native where performance is
very important, so it enjoys a ton of real-world usage.

—
You are receiving this because you authored the thread.
Reply to this email directly or view it on GitHub
https://github.com/facebook/react/issues/2608#issuecomment-219690343

When I use Ipod render time only one second.But when I use Android it takes seven seconds.

console.log(document.getElementsByTagName('*').length )
//min-length : 2700 , some may 5000

Android configuration is :

RAM : 2GB

CPU frequency : 2.0GHz
GPU : Imagination PowerVR G6200

Can I enhance the user experience?

Virtualized lists or MobX can solve it?

The solution to rendering a lot of items at once on the screen is virtualization - this is not a React specific problem - we've done this in other frameworks as well - and did this for our react datagrid component http://reactdatagrid.com

Although this depends on the structure of each row of data, beyond a certain number of rows you simply cannot achieve decent performance without virtualization - with or without react.

There is a library https://github.com/bvaughn/react-virtualized that implements virtualization that you may wish to investigate.

@mqliutie Clean console.log in Android. He will load the application.

I know this is an old issue. I am also having an issue rendering list of countries. It is very slow, although my case is react native. How can I increase the speed?

    const countriesMap = countries && countries.map(country => (
        <TouchableOpacity key={country.code} onPress={() => this.onCountrySelected(country)} >
            <View style={{ borderBottomWidth: 1, borderBottomColor: "#CCC", flexDirection: "row", paddingVertical: 10 }}><Text style={{ width: 50, paddingHorizontal: 10, borderRightWidth: 1, borderRightColor: "#CCC", marginRight: 20 }}>{country.code}</Text><Text>{country.name}</Text></View>
        </TouchableOpacity>
    ))

<Modal 
                        isVisible={this.state.visibleModal === 2}
                        onBackdropPress={this.closeModal} 
                        animationIn={'slideInLeft'}
                        animationOut={'slideOutRight'}
                        animationInTiming={800}
                        animationOutTiming={800}
                        backdropTransitionInTiming={2000}
                        backdropTransitionOutTiming={2000}
                        style={{ margin: 0, marginTop: 50 }}
                    >
                        <ScrollView style={{ flex: 1, backgroundColor: '#FFF' }}>
                            {countriesMap}
                        </ScrollView>
                    </Modal>

@smithaitufe https://github.com/bvaughn/react-virtualized will recycle rows not in view, when scrolling a massive list - this will lessen DOM size and result in faster UI speeds

Was this page helpful?
0 / 5 - 0 ratings

Related issues

krave1986 picture krave1986  Â·  3Comments

varghesep picture varghesep  Â·  3Comments

zpao picture zpao  Â·  3Comments

trusktr picture trusktr  Â·  3Comments

zpao picture zpao  Â·  3Comments