Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save swennemans/79e9a888412ceed2e1d9f49d9a043ab1 to your computer and use it in GitHub Desktop.
Save swennemans/79e9a888412ceed2e1d9f49d9a043ab1 to your computer and use it in GitHub Desktop.
Performance Conditionally Rendered Content in React

Performance Conditionally Rendered Content in React

First, this is not about if in JSX. It's just the simplest example to talk about (and a lot of people tried to do it at first a long time ago).

Some react components conditionally render content. When React first went public, a lot of us coming from handlebars really wanted "if" syntax. This gist isn't just about If components though, it's about any component that has an API that conditionally renders stuff.

{{#if stuff}}
  <div>Thing</div>
{{/if}}

And so we made stuff like this:

<If cond={stuff}>
  <div>Thing<Div>
</If>

And then <If> was implemented like so:

const If = ({ cond, children }) => (
  cond ? children : null
)

Works great, but there's a performance issue, every render you are calling createElement on the div. Remember, JSX transpiles to this:

React.createElement(
  If,
  { cond: stuff },
  React.createElement(
    'div',
    null,
    'Thing'
  )
)

So every render we're calling createElement('div') even though it never gets rendered. For small bits of UI, this isn't really a problem, but it's common for a large portion of your app to be hiding conditionally behind that If.

So, when you've got a component that conditionally renders some of the children it was passed, consider using a render prop as the children instead:

<If cond={stuff}>
  {() => (
    <div>Thing</div>
  )}
</If>

And then If looks like this:

const If = ({ cond, children }) => (
  cond ?  children() : null // called as a function now
)

This is good because now we aren't calling createElement('div') unless it's actually rendered.

Again, not a big deal in small cases, but for something like React Router Match or React Media, your entire app may live inside of a <Media> or <Match> component, and you calling createElement every render of your entire app that isn't actually rendered would cause performance issues.

So, if you conditionally render content, consider using a render prop.

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