Chapter 11. Performance tuning

React’s DOM diffing allows you to effectively discard your entire UI at any point in time with minimal impact on the DOM. There are, however, cases where the delicate tuning of a component should render a new virtual DOM representation that can help make your application faster. For instance, this is useful if you have a very deeply nested component tree. In this chapter we will cover a simple configuration you can provide to your component to help speed up your application.

shouldComponentUpdate

When a component is updated, either by receiving new props or setState being called, React will invoke the render method on each child component of that component. In most cases this performs without a hitch, but on pages with deeply nested component trees or a complex render method, you can experience some sluggishness.

Sometimes a component’s render method is invoked when it doesn’t need to be. This can happen when your component doesn’t use state or props, or if the props or state don’t change when the parent re-rendered. So, rendering the component again would yield the same exact virtual DOM representation that’s already present, which would be unnecessary.

React provides the component lifecycle method shouldComponentUpdate, which gives you a way to help React make the right decision of whether or not to invoke specific component’s render method.

shouldComponentUpdate should return a boolean. false tells React to not invoke the component’s render method and use the previously rendered virtual DOM. Returning true will tell React to invoke the render method on the component to get a new virtual DOM representation. By default shouldComponentUpdate returns true and components will thus always re-render.
Note that shouldComponentUpdate is not called on the initial render of a component.

shouldComponentUpdate receives the new props and state as arguments to help your make a decision of whether or not to re-render. For example a component with one prop and no state can look like this:

  shouldComponentUpdate(nextProps, nextState){
    if (this.props.data !== nextProps.data) {
      return true;
    }
    return false;
  }

For pure components that always render the same given the same props and state, you can add the react-addons-pure-render-mixin. Because we’re using ES6 classes, we need a library called react-mixin (https://github.com/brigand/react-mixin) that allows you to use the mixin. This is one of the few cases where mixins should be used instead of high order components.

You can read the full source code of our example application, a reddit clone, at http://git.io/vlcpa

The mixin will overwrite shouldComponentUpdate to compare the new props and state with the old, and return false if they are equal like in the above example.

A few of the components are this simple, like EditEssayQuestion, which you can use React.addons.PureRenderMixin with:

import reactMixin from 'react-mixin';
import PureRenderMixin from 'react-addons-pure-render-mixin';
class Foo extends React.Component {
  render(){
    ...
  }
}
reactMixin.onClass(Foo, PureRenderMixin);

In cases where you have deep complex props or state, the comparison can be slow. To help mitigate this, consider using immutable data structures like those discussed in Chapter 16.

Key

Most often you’ll find the key prop used in lists. Its purpose is to identify a component to React by more than the component class. For example, if you have a div with key="foo,” which later changes to “bar," React will skip the diffing and throw out the children completely, rendering from scratch.

This can be useful when rendering large subtrees to avoid a diff, which you know is a waste of time. In addition to telling it when to throw out a node, in many cases it can be used when the order of elements changes. For example, consider the following render that shows items based on a sorting function.

var items = sortBy(this.state.sortingAlgorithm, this.props.items);
return items.map(function (item) {
  return <img src={item.src} />;
});

If the order changes, React will diff these and determine the most efficient operation is to change the src attribute on some img elements. This is very inefficient and will cause the browser to consult its cache, possibly causing new network requests.

To remedy this, you can simply use some string (or number) you know is unique to each item, and use it as a key.

return <img src={item.src} key={item.id} />;

Now React will look at this and instead of changing src attributes, it will realize the minimum insertBefore operations to perform, which is the most efficient way to move DOM nodes.

In addition to the order changing, insertions that aren’t at the end also apply. Without correct key attributes, prepending an item to the array causes the src attribute of all following <img> tags.

It’s also valuable to note that while you seemingly pass the key in as a prop, it is not accessible in anyway from within a component.

Summary

In this chapter you learned how to:

  1. Modify shouldComponentUpdate to return true/false for added performance.
  2. Using key to help inform React of the minimum changes to a list of child components.

So far we’ve focused on using React in the browser, next you’ll learn about universal (also know as isomorphic) applications: JavaScript with React on the server.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.147.79.250