Adding Placeholders Until Heavy Component Creation and Loader for Initial Page in ReactJS

Guidance to improve the user interactivity until your heavy JS is being processed.

Viran Malaka

--

Are you dealing with a massively underperform react app? This guide is for you and all the ‘Curious George’s about React Performance in a mission-critical app.

Hello, world!.

Today I am going to talk about some tricks you can implement in your heavy ReactJS application. Briefly,

  1. Show a dummy element while creating larger components.
  2. A loader when the application initially mounting.

First of all, I need to talk about the importance of front-end performance. Everything depends on users opinion about the application. Let’s imagine the famous seen in Zootopia movie.

In the real world, if you ask something from your friend and he/she did not respond quickly, you tend to get disappointed about that person. right? The same scenario goes here as well. If the user does something in the webpage and that person cannot see any reaction from the GUI, they will definitely be frustrated.

As web developers, we need to provide some immediate reaction to their actions. It does not have to be the exact output. For example, on a button press, you want to show some fetched data from the API. Let’s “assume” it takes more time than intended due to network speeds. So why not attach a loader icon until the data is being fetched? Otherwise, the user thinks “I clicked this button, but nothing happened 🤨 🤔 😑”. In a data grid, when user scrolls, it should start scrolling right away. No need to show the real or fancy rows at first. But users need to see the grid scrolling when they requested that action.

Showing a simple placeholder element for a heavy component.

If your react component take too much time to render for the first time (mounting), it’s scripting time is very high. If that component is a row or a cell of a data grid, then you should have trouble in scrolling the grid.

Here, I am going to introduce a new pattern to attach the new component asynchronously to the DOM. Until that heavy component is being created we can show a small placeholder element which is smaller in size.

class ComponentAsyncLoader extends React.Component {
state = {
component: null,
};
componentDidMount() {
// set the component state asynchronously
setTimeout(() => {
this.setState({
component:
<THE_LARGE_COMPONENT {...this.props} />,
});
});
}
render() {
return (
this.state.component || (
<div className="placeholder-styles">
YOUR NICE PLACEHOLDER
</div>
)
);
}
}

Explanation:

  • Replace your component with a wrapper component.
  • This component has a local state and the variable value is initially set to null. Then, when this component is first appearing, your placeholder element will be shown because of the state value is null
  • In componentDidMount () {} the actual component is set to the state.
  • Until that heavy component is being created, the placeholder which shows in the first rendering cycle is visible to the user and he/she knows that there is something happening to his/her action.
  • In the second rendering cycle, your fancy component output will be shown. Simple right ?.

Add Lader animation in landing page

Your application will get bigger and bigger with time. Therefore the bundled javascript files that need to be transferred to the user’s browser will definitely increase. The size of the javascript files is proportional to the network time and that leads to the increased user waiting time. You can limit javascript file size through techniques such as minification and bundling. Well, you and I both know you can’t reduce the file size to 1 byte in a heavy JS app. Do you really consider to keep your users waiting until your massive code is being processed? DEAD!.

As we all know, when you go to a webpage, the first thing that loads is the index.html file. This is a typical index.html file in a React app.

<!DOCTYPE html>
<html lang="en">
<head>
<-- some meta tags here -->
<title>React App</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div><script src="/static/js/bundle.js"></script>
<script src="/static/js/0.chunk.js"></script>
<script src="/static/js/main.chunk.js"></script>
</body>
</html>

It has the reference to your JS files that needs fetching. After your index.html is loaded, your valuable users have to wait until the huge JS files load and complete processing in the browser. I am not going to provide you a solution to reduce that waiting time because as I said there are limitations on minification. But rather than showing nothing (white space), adding a loader on the web page will increase user satisfaction. After React finished loading, it replaces the <div id="root"></div> element by its own component’s output. So we can use that element to show a loader to the user. See the code below.

<!DOCTYPE html>
<html lang="en">
<head>
<-- some meta tags here !-->
<title>React App</title>
<style media="screen" type="text/css">
.loading {
-webkit-animation: sk-scaleout 1.0s infinite ease-in-out;
animation: sk-scaleout 1.0s infinite ease-in-out;
background-color: black;
border-radius: 100%;
height: 6em;
width: 6em;
}
.container {
align-items: center;
background-color: white;
display: flex;
height: 100vh;
justify-content: center;
width: 100vw;
}
@keyframes sk-scaleout {
0% {
-webkit-transform: scale(0);
transform: scale(0);
}
100% {
-webkit-transform: scale(1.0);
opacity: 0;
transform: scale(1.0);
}
}
</style>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root">
<div id="spinner" class="container">
<div class="loading"></div>
</div>
</div>
<-- full set of javascripts !-->
<script src="/static/js/bundle.js"></script>
<script src="/static/js/0.chunk.js"></script>
<script src="/static/js/main.chunk.js"></script>
</body>
</html>

This will show simple loading animation to the user until the browser loads required JS files and start the React app render.

--

--