React Tutorial: Top 7 optimization techniques in React App

React Tutorial: Top 7 optimization techniques in React App

In this article, you'll learn various optimization methods that use these inbuilt APIs, lifecycle methods and some other general techniques that ensure you improve your React code

In this article, you'll learn various optimization methods that use these inbuilt APIs, lifecycle methods and some other general techniques that ensure you improve your React code

One key factor for positive user experience is speed i.e how much time a user has to wait to first see contents from your website or application. Amazon reports a 1% sales loss for every 100ms load time, Walmart reports a +2% conversion per one second load time improvement.

Negative statistics lead to a decrease in user satisfaction and eventually customers. One solution to mitigating this is to properly optimize your application.

In computer science, optimization is the selection of the best element (with regard to some criterion) from some set of available alternatives.

React allows us to build encapsulated components that manage their own state, then composes them to make complex UIs.

These components make up small parts of our UI. This means a lot of times we unintentionally create redundant components and structure our code in ways that can impact the overall loading time of our application.

As stated earlier, the solution is optimization, and in this case, we can describe it as the best way we can write a particular code block, function or component to achieve re-usability and reduce the time taken to return information mostly in a near instant manner.

With the help of some inbuilt APIs like React.Component, React.PureComponent and life-cycle methods React offers, we can optimize our components to ensure fast and efficient load times in our applications.

Typically, our components are composed of CSS, JS and HTML code. Being able to determine when certain pieces show up will have a great impact on your page speed.

1 - How to use React.Fragment to avoid adding extra nodes to the DOM

At some point in your application, you will need to return multiple elements. From a table list to a group of related texts you will definitely reach scenarios where you need to return a group of data.

Your code will look something like this:

// Parent.js
class Parent extends React.Component {
    render() {
        return (
            <h1>Hello there!</h1>
            <h1>Hello there again!</h1>
        )
    }
}

If you are using a linter you will see the error: JSX parent expressions must have one parent element you will be forced to wrap both elements in a parent element aka div like so:

<div>
  <h1>Hello there!</h1>
  <h1>Hello there again!</h1>
</div>

Even though everything works fine, an extra unnecessary div is created. This can lead to so many useless elements being created around our application and can also cause invalid HTML in some cases where our render data is coming from a child component in a specific order. Consider the following code:

// Table.js
class Table extends React.Component {
  render() {
    return (
      <table>
        <tr>
          <Columns />
        </tr>
      </table>
    );
  }
}

class Columns extends React.Component {
  render() {
    return (
      <div>
        <td>column one</td>
        <td>column two</td>
      </div>
    );
  }
}

The above code will render the following in our table component:

<table>
  <tr>
    <div>
      <td>column one</td>
      <td>column two</td>
    </div>
  </tr>
</table>

This is definitely not the intended output as it is an invalid HTML syntax. Fragment solves this for you. We can re-write our column component to:

// columns.js
class Columns extends React.Component {
  render() {
    return (
      <React.Fragment>
        <td>column one</td>
        <td>column two</td>
      </React.Fragment>
    );
  }
}

Now you get the intended output and even better no extra DOM node is created. This may seem small but in reality the more elements on a page the more time it will take to load. Therefore auditing pieces of your code and updating them to use fragments to group data where necessary will definitely improve your code and it’s performance. Find out more about fragments here.

2 - Use React.Suspense and React.Lazy to load components declaratively

Typically, you want to load parts of your app only when they are requested. For instance, loading shopping cart data only when the cart icon is clicked, loading images at the bottom of a long image list when the user scrolls to that point, etc.

Lazy loading is a popular optimization technique widely used to speed up the load time of applications.

React.Lazy helps us load components on demand thereby reducing the load time of our application as only the needed pieces will be present as requested.

With its simple syntax, it can be used easily without hassle. It takes a callback function as a parameter that will load the component’s file using the dynamic import() syntax.

// MyComponent.js
class MyComponent extends Component{
    render() {
        return (<div>MyComponent</div>)
    }
}
const MyComponent = React.lazy(()=>import('./MyComponent.js'))
function App() {
    return (<div><MyComponent /></div>)
}

Behind the scenes, at compile time a separate bundle is created by our webpack when it hits the React.lazy() and import() statement. This process is called Code-Splitting. Our final app will be separated into multiple bundles containing UI pieces that would be loaded whenever they are required.

3 - Use React Suspense

In the time the component will be swapped in, a small time lag will occur leaving a screen freeze experience for your user. To give the user update or feedback on the outcome of the process React.Suspense is used.

React.Suspense is used to wrap lazy components to show fallback content while loading the component.

// MyComponent.js
const Mycomponent = React.lazy(()=>import('./component.js'))
function App() {
    return (
    <div>
        <Suspense fallback={<div>loading ..</div>}>
            <MyComponent />
        </Suspense>
    </div>)
}

Now, whenever the component is being loaded and there’s a delay a fallback text **loading. . **will be rendered. Find out more about React.Suspense and .Lazy here.

4 - Prevent unnecessary re-rendering with shouldComponentUpdate()

Most times in our application, we end up having instances of one component present on the screen. For example, on a blog page, we might have different blog posts show up via a blog post component that in turn also renders like button components. If not properly managed, a change in the state of a button component can cause all of the button components to re-render. The solution to this is using shouldComponentUpdate method.

shouldComponentUpdate() is used to let React know if a component’s output is not affected by the current change in state or props. By default, it re-renders on every state change. It always returns a boolean as a response — if the component should re-render or not. The default is that it always returns true.

A shouldComponentUpdate method is called with nextProps as the first argument and nextState as the second:

shouldComponentUpdate(nextProps, nextState){
    return nextProps.next !== this.props.next  
}

Now, if the next prop hasn’t changed there’s no reason to change the appearance of the component by re-rendering. This may not seem like huge improvements, however, in an application with so many components re-rendering shouldComponentUpdate will help improve performance.

N/B: shouldComponentUpdate can cause unintended problems if you set it and forget , because your React component will not update normally. Consider using the built-in PureComponent instead of writing shouldComponentUpdate() by hand.## 5 - Use React.PureComponent

Instead of using shouldComponentUpdate method in our components, React introduced a new component with built-in shouldComponentUpdate implementation, the React.PureComponent component.

React.PureComponent is similar to React.Component. The difference between them is that React.Component doesn’t implement shouldComponentUpdate(), but React.PureComponent implements it with a shallow prop and state comparison.

No extra code is needed, all you need to do is to use it in your class declaration:

// use this
class MyComponent extends React.PureComponent{
    render() {
        return (<div>MyComponent</div>)
    }
}
// instead of
class MyComponent extends React.Component{
    render() {
        return (<div>MyComponent</div>)
    }
}

Now with our pure component we no longer have to write:

shouldComponentUpdate(nextProps, nextState){
    return nextProps.next !== this.props.next  
}

It already implements this by default for us.

Although this is the recommended way to use shouldComponentUpdate only extend PureComponent when you expect to have simple props and state, or use forceUpdate() when you know deep data structures have changed. Or, consider using immutable objects to facilitate fast comparisons of nested data. Find out more here.

6 - Remove unused DOM elements with ComponentDidUnmount()

When working with React it is important to think of what happens when an element is removed from the DOM. Do they really go away? Or does the code just lie around even though it is not displayed to the user?

Having unused code around causes a problem called memory leak. React solves this for us by providing us with the componentWillUnmount method.

componentWillUnmount() is used to stop any unused code from running when a component is removed from the DOM.

You can perform several cleanups with this method, such as invalidating timers, canceling network requests, or cleaning up any subscriptions that were created in componentDidMount().

Consider the following component:

// App.js
class App extends Component {
    constructor(props) {
        super(props);
        this.state = {};
    }
    componentDidMount() {
        document.addEventListener("click", this.closeMenu);
    }
    openMenu = () => { }
    closeMenu = () => { }
    render() {
        return (
          <a href ="#" onClick = {this.closeMenu}>X</a>
        );
    }
}

In the above code, when you click the X link without the componentDidUnmount() the menu is closed but the event listener which was created when the component was mounted is still available.

To fix that, we can add a componentDidUnmount() to our component:

componentWillUnmount() {
   document.removeEventListener("click", this.closeMenu);
}

Now, when the button is clicked the event listener is removed with the **componentDidUnmount() **method.

N/B: You should not call setState() in componentWillUnmount() because the component will never be re-rendered. Once a component instance is unmounted, it will never be mounted again. Learn more about it here.## 7 - Use React.Memo to cache components

One way to speed up an application is by implementing memoization.

Memoization is an optimization technique used to primarily speed up programs by storing the results of expensive function calls and returning the cached results when the same inputs occur again.
A memoized function is faster because if the function is called with the same values as the previous one instead of executing function logic, it will instead fetch the result from cache.

In React, it is not uncommon for a component to change state multiple times. It is also not uncommon for some components to exist without the need to change state. If you have several components that rarely change state you should consider caching them.

React.Memo provides us with an easy API to implement memoization. It became available in React V16.6.0. Consider the following component:

// userDetails.js
const UserDetails = ({user}) =>{
    const {name, occupation} = user;
    return (
        <div>
            <h4>{name}</h4>
            <p>{occupation}</p>
        </div>
    )
}

Currently, every time the userDetails function is called it executes the function over and over again even if these details rarely change. We can use React.memo to cache it:

export default React.memo(UserDetails)

That’s all! As you can see no complex code is required. Simply wrap your component in the React.memo function and React takes care of the rest for you.

React.memo is a higher order component. It’s similar to React.PureComponent but for function components instead of classes. Find out more here.## Conclusion

In this tutorial, we explored several ways we can optimize our React components for better performance. We discussed only a few as there are lots of ways and tools used when optimizing an application.

Optimizing applications should be as needed because in some simple scenarios optimizing your components might be a killer.

One thing to keep in mind is the size and complexity of your project, would it be used for just demo or simple use cases? Or would it be deployed to be used every day by people? If the latter is the case then it may be time to think about optimizing your application.

JavaScript developers should you be using Web Workers?

JavaScript developers should you be using Web Workers?

Do you think JavaScript developers should be making more use of Web Workers to shift execution off of the main thread?

Originally published by David Gilbertson at https://medium.com

So, Web Workers. Those wonderful little critters that allow us to execute JavaScript off the main thread.

Also known as “no, you’re thinking of Service Workers”.

Photo by Caleb Jones on Unsplash

Before I get into the meat of the article, please sit for a lesson in how computers work:

Understood? Good.

For the red/green colourblind, let me explain. While a CPU is doing one thing, it can’t be doing another thing, which means you can’t sort a big array while a user scrolls the screen.

This is bad, if you have a big array and users with fingers.

Enter, Web Workers. These split open the atomic concept of a ‘CPU’ and allow us to think in terms of threads. We can use one thread to handle user-facing work like touch events and rendering the UI, and different threads to carry out all other work.

Check that out, the main thread is green the whole way through, ready to receive and respond to the gentle caress of a user.

You’re excited (I can tell), if we only have UI code on the main thread and all other code can go in a worker, things are going to be amazing (said the way Oprah would say it).

But cool your jets for just a moment, because websites are mostly about the UI — it’s why we have screens. And a lot of a user’s interactions with your site will be tapping on the screen, waiting for a response, reading, tapping, looking, reading, and so on.

So we can’t just say “here’s some JS that takes 20ms to run, chuck it on a thread”, we must think about where that execution time exists in the user’s world of tap, read, look, read, tap…

I like to boil this down to one specific question:

Is the user waiting anyway?

Imagine we have created some sort of git-repository-hosting website that shows all sorts of things about a repository. We have a cool feature called ‘issues’. A user can even click an ‘issues’ tab in our website to see a list of all issues relating to the repository. Groundbreaking!

When our users click this issues tab, the site is going to fetch the issue data, process it in some way — perhaps sort, or format dates, or work out which icon to show — then render the UI.

Inside the user’s computer, that’ll look exactly like this.

Look at that processing stage, locking up the main thread even though it has nothing to do with the UI! That’s terrible, in theory.

But think about what the human is actually doing at this point. They’re waiting for the common trio of network/process/render; just sittin’ around with less to do than the Bolivian Navy.

Because we care about our users, we show a loading indicator to let them know we’ve received their request and are working on it — putting the human in a ‘waiting’ state. Let’s add that to the diagram.

Now that we have a human in the picture, we can mix in a Web Worker and think about the impact it will have on their life:

Hmmm.

First thing to note is that we’re not doing anything in parallel. We need the data from the network before we process it, and we need to process the data before we can render the UI. The elapsed time doesn’t change.

(BTW, the time involved in moving data to a Web Worker and back is negligible: 1ms per 100 KB is a decent rule of thumb.)

So we can move work off the main thread and have a page that is responsive during that time, but to what end? If our user is sitting there looking at a spinner for 600ms, have we enriched their experience by having a responsive screen for the middle third?

No.

I’ve fudged these diagrams a little bit to make them the gorgeous specimens of graphic design that they are, but they’re not really to scale.

When responding to a user request, you’ll find that the network and DOM-manipulating part of any given task take much, much longer than the pure-JS data processing part.

I saw an article recently making the case that updating a Redux store was a good candidate for Web Workers because it’s not UI work (and non-UI work doesn’t belong on the main thread).

Chucking the data processing over to a worker thread sounds sensible, but the idea struck me as a little, umm, academic.

First, let’s split instances of ‘updating a store’ into two categories:

  1. Updating a store in response to a user interaction, then updating the UI in response to the data change
  2. Not that first one

If the first scenario, a user taps a button on the screen — perhaps to change the sort order of a list. The store updates, and this results in a re-rendering of the DOM (since that’s the point of a store).

Let me just delete one thing from the previous diagram:

In my experience, it is rare that the store-updating step goes beyond a few dozen milliseconds, and is generally followed by ten times that in DOM updating, layout, and paint. If I’ve got a site that’s taking longer than this, I’d be asking questions about why I have so much data in the browser and so much DOM, rather than on which thread I should do my processing.

So the question we’re faced with is the same one from above: the user tapped something on the screen, we’re going to work on that request for hopefully less than a second, why would we want to make the screen responsive during that time?

OK what about the second scenario, where a store update isn’t in response to a user interaction? Performing an auto-save, for example — there’s nothing more annoying than an app becoming unresponsive doing something you didn’t ask it to do.

Actually there’s heaps of things more annoying than that. Teens, for example.

Anyhoo, if you’re doing an auto-save and taking 100ms to process data client-side before sending it off to a server, then you should absolutely use a Web Worker.

In fact, any ‘background’ task that the user hasn’t asked for, or isn’t waiting for, is a good candidate for moving to a Web Worker.

The matter of value

Complexity is expensive, and implementing Web Workers ain’t cheap.

If you’re using a bundler — and you are — you’ll have a lot of reading to do, and probably npm packages to install. If you’ve got a create-react-app app, prepare to eject (and put aside two days twice a year to update 30 different packages when the next version of Babel/Redux/React/ESLint comes out).

Also, if you want to share anything fancier than plain data between a worker and the main thread you’ve got some more reading to do (comlink is your friend).

What I’m getting at is this: if the benefit is real, but minimal, then you’ve gotta ask if there’s something else you could spend a day or two on with a greater benefit to your users.

This thinking is true of everything, of course, but I’ve found that Web Workers have a particularly poor benefit-to-effort ratio.

Hey David, why you hate Web Workers so bad?

Good question.

This is a doweling jig:

I own a doweling jig. I love my doweling jig. If I need to drill a hole into the end of a piece of wood and ensure that it’s perfectly perpendicular to the surface, I use my doweling jig.

But I don’t use it to eat breakfast. For that I use a spoon.

Four years ago I was working on some fancy animations. They looked slick on a fast device, but janky on a slow one. So I wrote fireball-js, which executes a rudimentary performance benchmark on the user’s device and returns a score, allowing me to run my animations only on devices that would render them smoothly.

Where’s the best spot to run some CPU intensive code that the user didn’t request? On a different thread, of course. A Web Worker was the correct tool for the job.

Fast forward to 2019 and you’ll find me writing a routing algorithm for a mapping application. This requires parsing a big fat GeoJSON map into a collection of nodes and edges, to be used when a user asks for directions. The processing isn’t in response to a user request and the user isn’t waiting on it. And so, a Web Worker is the correct tool for the job.

It was only when doing this that it dawned on me: in the intervening quartet of years, I have seen exactly zero other instances where Web Workers would have improved the user experience.

Contrast this with a recent resurgence in Web Worker wonderment, and combine that contrast with the fact that I couldn’t think of anything else to write about, then concatenate that combined contrast with my contrarian character and you’ve got yourself a blog post telling you that maybe Web Workers are a teeny-tiny bit overhyped.

Thanks for reading

If you liked this post, share it with all of your programming buddies!

Follow us on Facebook | Twitter

Further reading

An Introduction to Web Workers

JavaScript Web Workers: A Beginner’s Guide

Using Web Workers to Real-time Processing

How to use Web Workers in Angular app

Using Web Workers with Angular CLI


Why ReactJS is better for Web Application Development?

Why ReactJS is better for Web Application Development?

Web Application Development is the point of contact for a business in today's digital era. It is important to choose the right platform for Web Application Development to build a high end Web

Web Application Development is essential for a business in today’s digital era. Finding the right platform for Web Application Development is important for building an effective Web Application that can enhance the overall customer engagement. Here’s what makes ReactJS a better option for building your next Web Application.