I haven't built many React-based projects yet, especially projects where size and performance become significant concerns... Until Braytech. It's in the Archive—check it out!
Lots of components, lots of HOCs, lots of asynchronous activity.
Braytech is one of my test beds, one of the projects I lean on for learning React and new principles. So there's occasions where I haven't looked at code I wrote when I first started the project and as well all know, past self is dumb. 🤪
I've refined Braytech a lot over the past few months. I've re-designed and re-written a lot of code, usually for the better. As I've done so, I've found myself increasingly considering performance of these components, and what's the better way to approach solving a problem. The usual self-improvement stuff, you could say.
Passing down unnecessary props
Despite the fact I've understood the effects of spreading props for a long time, I've only just recently considered how spreading unnecessary props and state could adversely affect performance by triggering needless reconciliations.
Accordingly, the past few weeks I've been spending a chunk of time searching the whole project for instances where I have unnecessarily spread all of the Redux state.
Object literals defined in render
Usually, I stick to writing CSS the old fashioned way with a stylesheet, but there have been instances where I have passed an object literal as a prop to a component or in JSX.
The case to look out for is where by the object is defined in a component's render function. The problem being is that each time the render function is executed (often), React will create a new unique reference to that object.
When it comes time for React to perform reconciliation between the DOM and virtual DOM, it will perform a shallow comparison and interpret them as being unique (different).
// Don't do this <Notification priority='high' style={{ backgroundColor: 'red', fontWeight: '900' }} /> // Do do this <Notification priority='high' style={notificationStyle} />
Anonymous functions
Similarly to object literals defined in render, anonymous functions defined in render will also cause unnecessary reconciliations.
// Don't do this <Button text='Reload' onClick={() => { setTimeout(() => { window.location.reload(); }, 50); }} /> // Do do this <Button text='Reload' onClick={this.reloadPagePlease} />