DEV Community

Cover image for Frontend Web Performance Checklist
Jakub Andrzejewski
Jakub Andrzejewski

Posted on

Frontend Web Performance Checklist

Improving performance of web applications will always be sexy. We want the page to load faster, smoother, and without too many layout shifts (Core Web Vitals, I am looking at you 😉). In this article I wanted to summarize all this knowledge into one single source of truth (with respect to article authors).

This summary document is based on the following articles:

and my own knowledge that I gathered throughout the years.

Make sure to visit these articles and give a solid like to all of them and their authors 😊

Preload key requests / Preconnect to required origins

Declare preload links in your HTML to instruct the browser to download key resources as soon as possible.



<head>
  <link rel="preload" href="critical.css" as="style">
  <link rel="preload" href="critical.js" as="script">
</head>


Enter fullscreen mode Exit fullscreen mode

Consider adding preconnect or dns-prefetch resource hints to establish early connections to important third-party origins.



<link rel="preconnect" href="https://example.com">
<link rel="dns-prefetch" href="https://example.com">.


Enter fullscreen mode Exit fullscreen mode

dns-prefetch works exactly the same as preconnect but has wider browser support.

Reduce third-party usage

Third-party code can significantly impact load performance. You can however modify the way you are using this third party library by:

  • Loading the script using the async or defer attribute to avoid blocking document parsing.
  • Self-hosting the script if the third-party server is slow.
  • Removing the script if it doesn't add clear value to your site.
  • Use link rel=preconnect or link rel=dns-prefetch to perform a DNS lookup for domains hosting third-party scripts.

Eliminate render blocking resources

Resources are blocking the first paint of your page. Consider delivering critical JS/CSS inline and deferring all non-critical JS/styles. You can reduce the size of your pages by only shipping the code and styles that you need.

Once you've identified critical code, move that code from the render-blocking URL to an inline script tag in your HTML page.

Inline critical styles required for the first paint inside a style block at the head of the HTML page and load the rest of the styles asynchronously using the preload link.

You can read more about this here

Minify/Remove unnecessary CSS and JS

When you are building a big application, you will get to a place where your project may have much more code that it actually needs and uses.

Use tools like CSS Minification or Terser JS Plugin.

To eliminate unused css use a tool like PurgeCSS.

To eliminate unnecessary JavaScript you can use Terser mentioned previously or utilize Tree Shaking to allow Dead Code Elimination. You can also use Code Splitting which will split code into bundles that can be loaded on demand.

Scan modules for duplicates

Remove large, duplicate JavaScript modules from bundles to reduce final bundle size.

image

Use Webpack Bundle Analyzer

Reduce execution time

The combination of code splitting, minification and compression, removal of unused code and caching techniques will greatly improve execution time.

Consider reducing the time spent parsing, compiling and executing JS. You may find delivering smaller JS payloads helps with this.
The idea is to optimize both our JS and CSS code, minimizing it and removing unused code, as well as the third-party libraries we are using.

Keep the server response time for the main document short because all other requests depend on it.

You can read more about this here

Image handling

Properly size images

Serve images that are appropriately-sized to save cellular data and improve load time.



<img src="cat-large.jpg" srcset="cat-small.jpg 480w, cat-large.jpg 1080w" sizes="50vw">


Enter fullscreen mode Exit fullscreen mode

You can read more about this here

Efficiently encode images

Optimized images load faster and consume less cellular data.
Using your image CDN service or the compression of your image should be enough.

You can read more about this here

And also you can read an article that I have released some time ago here

Serve images in next-gen formats

Image formats like WebP or Avif often provide better compression than PNG or JPEG, which means faster downloads and less data consumption.

You can read more about this here

Image elements have explicit width and height

Set an explicit width and height on image elements to reduce layout shifts and improve CLS.

You can read more about this here

Preload largest contentful paint (LCP)

Preload the image used by the LCP element in order to improve your LCP time.



<link rel="preload" href="/path/to/image.jpg" as="image">


Enter fullscreen mode Exit fullscreen mode


head() {
 return {
    link: [
      {
        rel: 'preload',
        as: 'image',
        href: 'path/to/lcp/image',
      },
    ],
  }
}


Enter fullscreen mode Exit fullscreen mode

You can read more about this here

Fonts

All text remains visible during webfont loads

Leverage the font-display CSS feature to ensure text is user-visible while webfonts are loading.



@font-face {
  font-family: 'Arial';
  font-display: swap;
}


Enter fullscreen mode Exit fullscreen mode

The font-display API specifies how a font is displayed. swap tells the browser that text using the font should be displayed immediately using a system font. Once the custom font is ready, it replaces the system font.

For Google fonts, for example, is as simple as adding the &display=swap parameter to the end to the Google Fonts URL:



<link href="https://fonts.googleapis.com/css?family=Roboto:400,700&**display=swap**" rel="stylesheet">


Enter fullscreen mode Exit fullscreen mode

You can read more about this here

What to avoid?

Large layout shifts

Cumulative Layout Shift (CLS) is a Core Web Vitals metric calculated by summing all layout shifts that aren’t caused by user interaction.

Avoid an excessive DOM size

A large DOM will increase memory usage, cause longer style calculations, and produce costly layout reflows.

Multiple page redirects

Redirects introduce additional delays before the page can be loaded.

Serving legacy JavaScript to modern browsers

Polyfills and transforms enable legacy browsers to use new JavaScript features. However, many aren't necessary for modern browsers.

Enormous network payloads

Large network payloads cost users real money and are highly correlated with long load times.

  • Defer requests until they're needed.
  • Optimize requests to be as small as possible, minimizing and compressing, try to use WebP for the images when it's possible. An image CDN will be always there to keep our performance up!
  • Cache requests so the page doesn't re-download the resources on repeat visits.

Document.write()

For users on slow connections, external scripts dynamically injected via document.write() can delay page load by tens of seconds.

Non-compositioned animations

Animations which are not composited can be heavy and increase CLS. Use translate and scale CSS properties instead.

Summary

You now know more about improving web performance. Just please remember that improving performance is not an issue that you can just sit once and fix. It is a continuous process and the topic of performance should be addressed regularly so that new features of your website (for sure needed) won't break the performance.

Top comments (3)

Collapse
 
hecktarzuli profile image
Josh Deltener • Edited

++ serve images from your own domain for faster LCP.

If you use assets from other domains (cloudinary, storyblok, etc..) the browser has to perform the dns lookup, tcp connection, ssl handshake, etc.. this can take up to 200ms! If you use assets from your own domain (NOT subdomains) this is already done so assets can start being downloaded instantly. This is the same concept as locally hosted fonts.

Even if you use an external CDN (ex: storyblok) you can still configure some hosting providers (ex: AWS) to map a folder from your domain into calling the external CDN so images still flow through your domain and are cached on your domain CDN. -- this is what we do.

Collapse
 
jacobandrewsky profile image
Jakub Andrzejewski

Very good suggestion Josh. Thank you for that!

And also thanks for sharing this with the readers of this article :)

Collapse
 
fruntend profile image
fruntend

Сongratulations 🥳! Your article hit the top posts for the week - dev.to/fruntend/top-10-posts-for-f...
Keep it up 👍