React Application Acceleration Fourfold

Original author: Dominik Tarnowski
  • Transfer
Almost 60% of site visitors leave it if it takes more than 3 seconds to load. 80% of such visitors are no longer returning to the site. This suggests that the success of a web project is not least dependent on its speed. The author of the material, the translation of which we publish today, wants to talk about techniques for improving the performance of React applications.


Application Optimization Results

Benchmarks


Before I tell you about how I accelerated the application, I want to show some numbers. Here the measurements were carried out in the expectation that they will work with the application using a connection that is rather slow by modern standards. But it should be noted that in reality most users will have faster connections.

  • In the course of measurements made by the Network tab of the Chrome developer tools, the data transfer rate was forcibly limited to the level of a fast 3G connection.
  • First Load metric obtained with cache disabled.
  • The 2nd Load indicator indicates the time of reloading the application when the cache is on.

As you can see, the difference between an optimized and non-optimized application is quite large. This is especially noticeable in slow networks.

The size of the application bundle was examined using source-map-explorer. This tool also lets you know how much space various libraries occupy. The indicators that can be seen at the top of the figure are measured using Google Lighthouse.

Now I’ll talk about how I optimized the application.

1. Using CSS instead of CSS-in-JS


In the old version of the application, I used the styled-components library. Why is this bad? The thing is, plain CSS is faster and takes up less space. Modern browsers can load CSS code in parallel with the JavaScript bundle. In addition, you do not need an additional library to use regular CSS. The minified version of styled-components takes about 54 Kb. Using regular CSS instead of styled-components led to the fact that the application code loads faster, and to the fact that when changing styles the system has to perform less computation.


Just dropping the styled-components library and switching to regular CSS can reduce the site load time by about 0.3 seconds.

If CSS allows for better performance than technologies that implement the CSS-in-JS scheme, you may wonder why developers use this technology stylization of components. Among the reasons for choosing CSS-in-JS are the fact that this technology allows you to limit the scope of styles and abandon global styling. It is convenient to use for working with application themes. And someone, maybe, just likes to style React applications that way.

▍ Styles with limited scope


Create-react-app now officially supports CSS modules with a limited scope. This means that you can limit the scope of styles without using additional libraries.

▍ Themes


If you work with the styled-components library, then in order to use the variables that define the themes, just wrap these variables in ThemeProvider. All this is good, but as of May 2019, 91% of browsers support a similar standard CSS feature.

If you believe that 91% is not a good enough indicator, consider that it may not be that small.


Support for CSS variables

Actually, if you are not interested in IE support, then you can safely use CSS variables in your projects. If you are interested in this topic - I recommend taking a look at this material.

2. Avoiding Large CSS Libraries



Analysis of the material-ui package

I am a big fan of Material Design. A great Material library called material-ui has been written for React. This library has only one problem. This is her size. She is very great. Even if you use only its individual components, its implementation of the CSS-in-JS mechanism will fall into the bundle, and this is approximately 30 Kb of minified code.

What are the alternatives? I decided to build my own components, styling them in the process of creating the application. One of the reasons for this choice was that I wanted to refresh my CSS knowledge. And I have not written CSS code for a long time. However, there are other possibilities. In particular, we are talking about CSS frameworks, the sizes of which are much smaller than the size of material-ui. For example, these are Specter and Bulma, the code of which takes, respectively, 9 and 40 Kb after GZIP compression.


Specter - 9 Kb after GZIP-compression


Bulma - 40 Kb after GZIP-compression

3. Lazy loading pages


So, you have a router with many imported pages. If we are talking about a couple of pages - there are no problems here. But as the number of pages increases, so does the time the site first displays. Here's what the import commands might look like:

import NotFound from"pages/NotFound";
import Projects from"pages/Projects";
import Project from"pages/Project";

How to improve it? Fortunately for us, React can organize lazy page loading. The same applies to the component code, which can be broken into small fragments, loaded when necessary. Here's what it looks like:

import React, { lazy, Suspense } from"react";
const load = (Component: any) => (props: any) => (
    <Suspensefallback={<Loader />}>
        <Component {...props} />
    </Suspense>
);
const NotFound = load(lazy(() => import("pages/NotFound")));
const Projects = load(lazy(() => import("pages/Projects")));
const Project = load(lazy(() => import("pages/Project")));

4. Progressive Web Application Technologies


Progressive web applications use service workers. They allow users to add applications to the home screens of their devices. But this is not limited to service worker options. In particular, they are able to significantly improve caching. This leads to the fact that the application, after the first download, will load much faster.

5. Getting rid of packages that seem interesting, but do not bring much benefit


In my original project, when I mounted the components, I used a lot of animation that animated the loading of the page. All this did not just slow down the page. This made her much slower than she could be. I, looking at the site, and rejoicing at how cute it looks, did not think about performance until a certain point. But the site was not only animated. There were other similar decorations. For example, a button that allows you to go to the top of the page. For example - animated loading of some elements. I liked all this, but upon closer inspection it turned out that, for example, the site really slows down on not the fastest devices. Moreover, at first I tested the site exclusively on a laptop, so I did not immediately learn about it.

I also had a slider component, which I added to the page without much thought about its “weight”. I used it for a slide show. As it turned out later, only the code of this slider occupied, in a minified form, 30 Kb. Then I decided to create a component for a slide show on my own. Its minified code, in the end, took 25 KB. This volume included a good animation library and a system for working with gestures that can be used not only for slide shows, but also in other parts of the application. And it looks like what I did is much better than a third-party solution.

Here is a slider from NPM.


NPM

slider Here is my slider


A slider of our own design (in life it works much more smoothly than on this GIF image with a low frame rate) You can

watch this slider in action here .

▍ Bundle Size Analysis


If you use create-react-app, then it’s very easy for you to analyze the composition of the bundle. To do this, run the command npm run build, and after that - the command npx source-map-explorer "build/static/js/*.js". After that, a page with information about the composition of the bundle will open, resembling the one shown below.


Bundle Information

Summary


As you can see, accelerating React applications is not so difficult. It is enough to carefully monitor what they are built from, test them and make appropriate changes to them. Here is the project that was discussed here, before improvement, and hereafter .

If you are interested in optimizing React applications, here are some of our publications on this topic:


Dear readers! Do you have any examples of successful (or unsuccessful) optimization of React applications?




Also popular now: