GAZAR

Principal Engineer | Mentor

How to Improve/Measure Performance in FrontEnd 2023

How to Improve/Measure Performance in FrontEnd 2023

It seems like a good time to talk about FrontEnd and performance, you have been given a task to dig into the performance of your website and make it better. What would you do?

I have an article here about JavaScript Event Listeners and how you can make them more performant.

I also have written another one here on how to measure your app’s performance.

and Here you can see how to optimise react components.

Let’s take it one step further, shall we?

Next Steps on Improving Performance:

Do you have Compression Enabled GZip/Brotli?

Brotli seems to be the solid solution by Google, offering better compression, have a look here (https://brotli.org/)

Primarily we are using Nginx, so you can have a read here and install it on your server.

and of course, if you search you can find other solutions for other servers.

You might be also using AWS Cloudfront and serving files from S3. in that case you need to enable it in your AWS Cloudfront.

Have a look at here:

  • https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/ServingCompressedFiles.html

and if you want to know why Brotli is better than GZip have a look here:

  • https://expeditedsecurity.com/blog/nginx-brotli

2. Are you using a CDN?

You can use a lot of features in CDN, caching globally, serving the files from different regions and compression and other features.

If you don’t make sure, all the assets you have are being served from a CDN. There are many out there, Probably Cloudflare and AWS CloudFront are the most famous ones.

3. Prefetching

Link prefetching is a browser mechanism, which utilizes browser idle time to download or prefetch documents that the user might visit in the near future.

This is not that difficult. just use the prefetch attribute:

<link
  rel="prefetch alternate stylesheet"
  title="Designed for Mozilla"
  href="mozspecific.css" />
<link rel="next" href="2.html" />

3. Remove Unused CSS/JS files

I mean, you are probably using Webpack, or any other build tool, you know how to bundle and compress your files! but even after that, you might have CSS and JS files that are unused.

If you want to know more about bundling, and minimising have a look at Terser and Terser plugins.

  • https://webpack.js.org/configuration/optimization
const TerserPlugin = require('terser-webpack-plugin');
module.exports = {
  optimization: {
    minimizer: [
      new TerserPlugin({
        parallel: true,
        terserOptions: {
          // https://github.com/webpack-contrib/terser-webpack-plugin#terseroptions
        },
      }),
    ],
  },
};

Have you seen the coverage tab in Chrome Devtool?

1_uU7c2O7yTAhNqqo8xKYslw.webp

have a look at your chrome DevTool, sources and Command+Shift+P and type Show Coverage and then refresh a page, you'll get exactly what is being used, not used and so on + marking the lines

Then you start identifying why and try to exclude as much as you can from these unused files.

Also, a simple hack in Webpack can remove assets with errors away from the page, in case they happen.

optimization: {
  emitOnErrors: true,
},  

3. Optimise your Images/Videos

Make sure you have an optimising image solution in your build tools.

Go to this page by webpack for example.

  • https://webpack.js.org/plugins/image-minimizer-webpack-plugin

and you can see you can optimise anything using different imagemin, squoosh, sharp and svgo.

4. Code Splitting

Perhaps a bit harder to set up if you don’t have it already, depends on your build tool and the most commonly used seems to be Webpack.

Entry Points

Easiest is to use different entry points and define them

https://webpack.js.org/guides/code-splitting/#root

entry: {
  index: './src/index.js',
  another: './src/another-module.js',
  shared: 'lodash', // if you have any
},
output: {
  filename: '[name].bundle.js',
},
optimization: {
  runtimeChunk: 'single',
}

Dynamic imports:

The JS version is as simple as

async function load() {
  let say = await import('./say.js');
  say.hi(); // Hello!
  say.bye(); // Bye!
  say.default(); // Module loaded (export default)!
}

However, with React, you get more options: like

import("./math").then(math => {
  console.log(math.add(16, 26));
});

or React Lazy

import React, { Suspense } from 'react';
const OtherComponent = React.lazy(() => import('./OtherComponent'));
function MyComponent() {
  return (
    <div>
      <Suspense fallback={<div>Loading...</div>}>
        <OtherComponent />
      </Suspense>
    </div>
  );
}

You can mix it with Suspense if you need to

https://reactjs.org/docs/code-splitting.html

and you can go ahead with an even better option for code splitting on React Router

import React, { Suspense, lazy } from 'react';
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
const Home = lazy(() => import('./routes/Home'));
const About = lazy(() => import('./routes/About'));
const App = () => (
  <Router>
    <Suspense fallback={<div>Loading...</div>}>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/about" element={<About />} />
      </Routes>
    </Suspense>
  </Router>
);

These are a bit harder to implement, but for sure it’s worth it.

5. Clean React Renders

The best tool ever to check this is to use React Profiler,

1_IAlNjUpI905qpJmgYnT_PQ.gif

Use it wisely in the DEV environment, have a look at this article for more detail

https://jsramblings.com/how-to-check-if-your-component-rerendered-and-why/

It’s always nice to bring those renders to a minimum and try to reduce the mutation of renders to the page or any other irrelevant components.

Wrap up:

Performance is as important as developing any feature, it’s a skill to talk to your business analyst or project manager to prioritise these tickets.

The point is to try to talk with numbers, use the tools to have measurements, percentages and seconds, and talk about how much you can possibly reduce those numbers.

Record videos of your screen, from tools, from highlighting tools and explain them in pictures/videos. Loom or Zappy are being so useful for quickly recording a video.

If you want to go further, write down documentation, step by step, and you can fix the performance. Always upgrading node modules is the first and everything else comes after. Easy ones with more impact should be after. Then try to go to more complicated ones and make sure you have all the testing in place to not break the website.

And lastly, ask for your lead’s support and your team’s support, and explain to them, there is a risk of breaking some areas, and you might need more time or testing in place.

Good Luck!