3

I had a CategoryPicker component which displays a large category tree(hierarchical, about 20,000 nodes), each of the node was bound to a onClick event handler in order to figure out which node the user is clicking.

It turns out to be extremely slow when mounting this component, profiling result shows that EventPluginHub.putListener consumes most of the resources.

The only solution I can think of is using jQuery to bind event handler to it's ancestor, you know, the old school way. But apparently this is against React's design philosophy.

const CategoryPicker = React.createClass({
  render() {
    return (
      // data has about 20,000 elements
      {data.map((d) => {
        return (
          <div onClick={this.handleClick.bind(this, d.cateId)} key={d.cateId}>
            {d.cateName}
          </div>
        );
      });}
    );
  }
});

profile result

Update

I've tried remove onClick event handler on the nodes, the performance boost is evident. Guess I have to use the jQuery way to handle this situation right now.

5
  • 1
    Just bind it to the parent/ancestor and have the event bubble up. I don't use react though, so why is it against the design philosophy? Seems odd. Commented Jul 3, 2015 at 9:33
  • 1
    Just a quick check: remove the event handler - is it still slow? Commented Jul 3, 2015 at 10:31
  • Also check this: jonmiles.github.io/react-performance-tests/react.html Just even rendering 20000 nodes is going to be a little slow. Commented Jul 3, 2015 at 10:34
  • I would also try removing the bind Commented Jul 3, 2015 at 11:49
  • @ColinRamsay removing the handler did boost the performance Commented Jul 5, 2015 at 4:21

2 Answers 2

1

Ideally you should be attaching the event handler to a parent component (just using react, no need for jquery) and let these events bubble up. You can then use the passed event object to determine which component was clicked.

If for some reason you want to avoid this, also consider the fact the bind itself will cause a lot of overhead. You are essentially creating a new function with every component.

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

Comments

0

I'm faced with code today that approached this "bubbling onClick on parent, data attributes on children" strategy everywhere. It's so painfull to read. I'd suggest using a virtual rendering system like react-table to only render the few categories visible to a user. You get a real performance boost, because you simply don't render 90% of your 20000 divs to start with. And it solves the problem of event listener with bound functions eating memory.

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.