Optimizing React SPA applications in benchmark tools
Technology
2
 min read
October 19, 2021

Optimizing React SPA applications in benchmark tools

Ján Cvenček
Ján Cvenček
Frontend Develooper

In this article, I will present solutions that can help with the optimization of SPA (single page app), primarily based on the React framework. Applying each procedure helps speed up loading, improve performance, and get higher scores in benchmark tools. In the first part I will focus on file compression, web fonts and CSS.

The tips below have been applied to a React application created with the Create React App (CRA), which uses webpack v4. CRA is preconfigured with several techniques for better application performance and speed. To modify the webpack configuration in CRA without executing the eject command, it is necessary to use libraries like craco or customize-cra. The production build of the application is served using the Nginx web server.

The following tools were used to measure performance and speed scores:

The tools themselves in the outputs suggest solutions to eliminate individual problems.

The following procedures are not the only way to solve the reported problem from the tools, several of them have an alternative.

Compression

The compression of the files served by the web server can be applied either on the server side or statically during the build process.

Compress-create-react-app

For static compression, the compress-create-react-app library can be used as a build script via npm. Performs gzip and brotli compression for html, css and js files. In case the compression is not sufficient, or its configuration is not good, it is possible to use one of the procedures below.

Gzip

The compression method is less CPU intensive, but the size of the compressed files is larger compared to Brotli. The individual methods can be extended with additional switches / parameters as required.

Static compression

It can be done using the system utility gzip (needs to be installed for Windows) gzip -r -f -k Since the utility is not cross- platform pre-installed , it is better to use compression-webpack-plugin.

Live compression - Nginx

Enables in the Nginx configuration.

Brotli

A more powerful method compared to gzip at the loss of CPU power.

⚠Supported just over HTTPS

Static compression

Using compression-webpack-plugin

Live compression - Nginx

It is enabled in the configuration for Nginx, which must have the Brotli module installed. For Docker it is possible to use e.g. fholzer/nginx-brotli

Imagemin

Image compression tool. There are several plugins for different formats. Each has several parameters for setting up the plugin as needed. Individual plugins with links are in the table. Supports lossless (image quality after compression matches the original) or lossy compression. Lossless compression is more efficient in terms of size savings at the expense of quality.

Example of a PNG compression via GULP

npm install gulp gulp-imagemin --save-dev

Lossless compression (imagemin-optipng)

npm install imagemin-pngquant --save-dev

Lossy compression (imagemin-optipng)

npm install imagemin-optipng--save-dev

Webfonts

Make sure the text is visible while loading web fonts. Fonts are often large files that take a while to load. Some browsers hide text until the font is loaded, which causes a flash of invisible text (FOIT) - Lighthouse metric.

Solution - add the font-display: swap; attribute to the @ font-face declaration

CSS

Before viewing the page, the browser must download and parse the CSS files, which makes the CSS a rendering-blocking resource. If the CSS files are large or the network conditions are bad, the requirements for the CSS files can significantly increase the time it takes to render the web page.

If the Lighthouse report reports a First Contentful Paint (FCP) problem - "Eliminate render-blocking resource" it is advisable to try the extraction of critical (they are currently needed for display) and non-critical CSS styles. After optimization, only critical styles are loaded synchronously, while non-critical ones are loaded in a non-blocking manner.

Possible solution- html-critical-webpack-plugin

The plugin uses the puppeteer library with the Chromium/Chrome headless browser - you need to make sure that the environment where the PROD build will run has the necessary dependencies installe

html-critical-webpack-plugin parses critical CSS styles and pulls them into a <style></style> in the <head> tag in HTML, eliminating the need to make another request to load them.

ℹ It is recommended to use the plugin only during the production build

Like what you see?
Join our newsletter.

Great! Welcome to newsletter.
Oops! Something went wrong while submitting your email.
High quality content once a month. No spam, we promise.
Your personal data is processed in accordance with our Memorandum on Personal Data Protection.

Páči sa vám náš content?
Odoberajte newsletter.

Great! Welcome to newsletter.
Oops! Something went wrong while submitting your email.
Vaše osobné údaje sú spracované v súlade s našim Memorandom na ochranu osobných údajov.