11 Tips for Optimizing Web Application Performance (Network Section)

How to do better?

Zachary Lee
Level Up Coding

--

Photo by Marc-Olivier Jodoin on Unsplash

Optimizing the performance of web applications is a troublesome job because the knowledge involved is messy. This article summarizes a few tips that can be optimized in the network section.

1. DNS prefetch

<head>
<link rel="dns-prefetch" href="https://fonts.googleapis.com/" />
</head>

Whenever your web application references resources on cross-origin domains, you should place the dns-prefetch hint in the <head> element.

This is because when the browser requests the resource, it will resolve the domain name to an IP address before making a request. This resolution process is DNS resolution. This can drastically reduce loading performance when your app references many different cross-origin resources. And dns-prefetch can help us mask DNS resolution latency.

MDN describes three best practices for us:

  1. Only used for cross-domain resources. This is because the IP behind your website is already resolved when the user visits your app.
  2. dns-prefetch (and other resource hints) can be specified as HTTP headers using the HTTP Link field.
  3. Consider pairing dns-prefetch with the preconnect hint. preconnect will help us establish a connection to the server, including DNS resolution, establishing a TCP connection, a TLS handshake (HTTPS), etc. But be careful to enable it only for those critical connections, because if a page connects to many third-party domains, pre-resolving and connecting them can be counterproductive.
<link rel="preconnect" href="https://fonts.googleapis.com/" crossorigin />
<link rel="dns-prefetch" href="https://fonts.googleapis.com/" />

Some resources such as fonts are loaded in anonymous mode. In such cases, you should set the crossorigin attribute with the preconnect hint. If you omit it, the browser will only perform the DNS lookup.

2. Preprocessing using link tags

Not only the dns-prefetch and preconnect mentioned above, the link tag also supports many preprocessing cases:

prefetch

<!-- Pre-download and cache a resource, usually a non-critical resource. -->
<!-- May be ignored when busy. -->

<link rel="prefetch" href="https://www.example.com" />

preload

<!-- Pre-download and cache a resource, usually for critical resources. -->
<!-- Not ignored when busy. -->

<link rel="preload" href="https://www.example.com" as="font" crossorigin />

prerender

<!-- Not only will the resources be downloaded, but also the execution page will be parsed and pre-rendered. -->
<link rel="prerender" href="https://www.example.com" />

modulepreload

<!-- A JS module is preloaded, and it will not be executed after the download is completed. -->
<link rel="modulepreload" href="app.js">

3. Script Tag — async & defer

The script element is very important for web applications, we can reasonably use the async and defer attributes of the script tag to reduce the above-the-fold loading time. I have an article detailing:

4. Image optimization

Optimizing image loading may be the most profitable if your app makes heavy use of images or icons.

For example: use a packaging tool (such as Webpack) to inline the small image with base64; compress the image; integrate multiple icon files into one image; choose a better image format, such as WebP, etc.; use SVG icons or use fonts Icons; use lazy loading for uncritical images, etc.

5. CDN

A CDN (Content Delivery Network) is a set of servers distributed in many locations. These servers store duplicate copies of data in order to return the server content closest to the end user. This can be a great buffer for high traffic cases.

Therefore, we can make reasonable use of CDN, such as deploying CDN servers in multiple places, and geographical distance will affect the delay proportionally; we can also place those static resources on CDN to reduce the request burden on our own servers, etc.

6. Request Domain Split

In browsers, the maximum number of TCP connections from the same origin is limited to 6. This means that if you use HTTP1.1 when sending more than 6 requests at the same time, the 7th request will wait until the previous one is processed before it starts.

So we can reasonably divide resources and split their domain names. In addition, combined with the CDN mentioned above, it is recommended to use a cookieless domain name for static resources.

7. HTTP Caching

Using HTTP caching allows us to speed up the fetching of resources, and it can be divided into strong and negotiation caching. Check out this article of mine for details:

In addition to this, we can also use the server-side push cache supported by HTTP2.

8. Local caching

We can cache the response content in memory, or store it locally. We can do all this using the storage API provided by the browser. In the following article I describe how to use blobs to cache resources locally:

9. Avoid redirects

Timely cleaning up resources and avoiding redirects can reduce our request time a lot.

10. Compression

We can use gzip, deflate, br compression. They are similar and exist in the content-encoding response header. Take gzip for example, a file format used for file compression and decompression. This allows for smaller files for faster network transfers. And it is widely supported in browsers and web servers. For example, here is a simple configuration for Nginx:

gzip on;
gzip_min_length 10k;
gzip_types text/plain application/javascript text/css text/javascript;
gzip_http_version 1.1;
gzip_vary on;

11. Code splitting

We can use the code splitting of the packaging tool to achieve on-demand loading, for example, dynamic imports allow us to do this.

Conclusion

Hope today’s optimization point can help you. If there is anything I haven’t mentioned, please share it with me in the comments.

Thanks for reading. If you like such stories and want to support me, please consider becoming a Medium member. It costs $5 per month and gives you unlimited access to Medium content. I’ll get a little commission if you sign up via my link.

Your support is very important to me — thank you.

--

--