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.
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 callback 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 callback.
This might change in the future by React team, until there, here is their code: https://twitter.com/ryanflorence/status/819266202455265280
Your tests get slow because you're doing in
NODE_ENV !== 'production'
, and with the debug console open JIT won't apply optimizations on that code, what speeds up that even more.About number of elements, 1000 elements it's a reasonable number of elements for a regular website. Those numbers you're basing your theory are edge cases.
This page have ~1k elements, a twitter dashboard have ~5k elements, facebook initial page have ~5k elements. A page with 100k to 1m elements need way more optimization that your solution.
I'm very sorry if the way I talk to you make you feel uncomfortable, look for the bright side, you might learn something here and help to drive the community to do better design choices, since your React-Router is that important.