Skip to content

Why is react so slow rendering 900 items? (with jsfiddle) #2608

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
VascoPessanha opened this issue Nov 26, 2014 · 21 comments
Closed

Why is react so slow rendering 900 items? (with jsfiddle) #2608

VascoPessanha opened this issue Nov 26, 2014 · 21 comments

Comments

@VascoPessanha
Copy link

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

@aackerman
Copy link
Contributor

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.

@VascoPessanha
Copy link
Author

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

@waldreiter
Copy link
Contributor

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');

@syranide
Copy link
Contributor

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.

@chenglou
Copy link
Contributor

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

@VascoPessanha
Copy link
Author

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

@ricardosoeiro
Copy link

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?

@ricardosoeiro
Copy link

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?

@syranide
Copy link
Contributor

syranide commented Dec 5, 2014

@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.

@aackerman
Copy link
Contributor

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.

@gaearon
Copy link
Collaborator

gaearon commented Dec 11, 2014

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).

@gaearon
Copy link
Collaborator

gaearon commented Dec 11, 2014

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.

@zpao
Copy link
Member

zpao commented Dec 12, 2014

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.

@wzup
Copy link

wzup commented May 17, 2016

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.

@gaearon
Copy link
Collaborator

gaearon commented May 17, 2016

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.

@VascoPessanha
Copy link
Author

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
#2608 (comment)

@mqliutie
Copy link

mqliutie commented Nov 4, 2016

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?

@flexicious
Copy link

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.

@arg0navt
Copy link

arg0navt commented Jul 1, 2017

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

@smithaitufe
Copy link

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>

@allanlaal
Copy link

@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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests