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.
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.
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.
In this chapter you learned how to:
shouldComponentUpdate
to return true/false for added performance.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.
3.147.79.250