Page Speed Insights

Page Speed Insights score of https://pthethanh.herokuapp.com/

Summary: The smaller size of HTML, JS, CSS and Images the better the performance.

Web page performance is one of the most important things in web development. The better performance means the better user experiences and the better business.

There are a lot of factors that impact the speed of web pages but in this post, I just list some major factors that impact the most to the performance of a web page and quickly show some solutions to address them.

Actually, these are just my notes during the journey of improving performance of this blog, but hopefully someone can be benefited from this too.

HTML, JS, CSS #

The best way to make web pages load fast is to reduce and minimize sizes of all relevant documents transferred from the web server. This includes HTML, JS, CSS, Images, Font,...

For HTML and CSS, we can use a lot of HTML/CSS optimizer and also enable compression mechanisms (gzip) on the server to reduce the size of the document. This alone contributes a lot to the web page performance.

For this blog, I use minify-html for HTML, minify-jsfor JS and TailwindCSS minifierfor CSS.

Below is the records of one of article in this blog:

Request count and transfer sizes of this blog

Request count and transfer sizes of this blog

Web Fonts #

Web Fonts can cause a lot of issues for web performance, such as: blocking resources, heavy font sizes, cumulative layout shift.

If you're using Google Web Fonts, you don't really need to do anything since they are already optimized very well. The only thing you need to do is to preload it in advance to avoid blocking resource issues.

<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link rel="preload" as="style" href="https://fonts.googleapis.com/css?family=Lobster" />
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Lobster" media="print" onload="this.media='all'" />
<noscript>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Lobster" />
</noscript>

If you use remote web fonts from other sites, Google Page Speed Insights might complain about the cache period of the fonts and hence reduce the score. To fix this problem, consider hosting the web fonts locally with a longer cache period..

If you're using other types of fonts, consider using woff2 for smaller size. Also sometimes fonts are composed of multiple languages and you don't really need them, consider using fonttools to create the subsets you need and use unicode-range of web fonts to tell the browsers to load a specific font only when needed.

fonttools subset latest.woff2 --unicodes="U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+1EA0-1EF9,U+20AB,U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD" --flavor="woff2"
/* vietnamese */
@font-face {
font-family: 'Lobster';
font-style: normal;
font-weight: 400;
src: url(https://fonts.gstatic.com/s/lobster/v27/neILzCirqoswsqX9zo2mM5Ez.woff2) format('woff2');
unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+1EA0-1EF9, U+20AB;
}
/* latin */
@font-face {
font-family: 'Lobster';
font-style: normal;
font-weight: 400;
src: url(https://fonts.gstatic.com/s/lobster/v27/neILzCirqoswsqX9zoKmMw.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

For a complete example of the final web font, see: https://fonts.googleapis.com/css?family=Lobster

Web font is also a big contributor for the cumulative layout shift, especially for the above-of-the-fold content. To reduce this problem, consider using font-display: optionalfor your web fonts. This prevents both font blocking and layout shift.

@font-face {
font-family: SegoeUI;
src:
local("Segoe UI"),
url(./west-european/normal/latest.woff2) format("woff2"),
url(./west-european/normal/latest.woff) format("woff"),
url(./west-european/normal/latest.ttf) format("truetype");
font-weight: 400;
font-display: optional;
}

Take advantage of system fonts is also a good trick to improve the performance of the web page:

Sans-serif
font-family: -apple-system, BlinkMacSystemFont, avenir next, avenir, segoe ui, helvetica neue, helvetica, Cantarell, Ubuntu, roboto, noto, arial, sans-serif;

Serif
font-family: Iowan Old Style, Apple Garamond, Baskerville, Times New Roman, Droid Serif, Times, Source Serif Pro, serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol;

Mono
font-family: Menlo, Consolas, Monaco, Liberation Mono, Lucida Console, monospace;

Images #

For image, consider to use WEBP or AVIF for smaller sizes. Use suitable image sizes for each purpose and for each type of display using picture tag with srcset and sizes.

Image might cause issues with layout shift, hence consider to set its size (set for mobile) to a fixed number. Enable async decoding and lazy loading for better performance. But for the above-of-the-fold image, lazy loading should be disabled because we want it to be loaded as fast as it can to reduce the First Content Paint time.

For the above-of-the-fold image, disable lazy loading, set the size fits the sizes of mobile.

<picture class="object-center object-cover w-full">
<source sizes="50vw" srcset="https://res.cloudinary.com/pthethanh/image/upload/v1636264048/effective-options/options-w1280.webp 1280w,https://res.cloudinary.com/pthethanh/image/upload/v1636264049/effective-options/options-w640.webp 640w,https://res.cloudinary.com/pthethanh/image/upload/v1636264049/effective-options/options-w320.webp 320w" type="image/webp">
<img decoding="async" width="359" height="240" class="object-center object-cover bg-none w-full mb-2" src="https://res.cloudinary.com/pthethanh/image/upload/v1636264047/effective-options/options-worg.jpg" alt="unsplash/Victoriano Izquierdo">
</picture>

For other types images in the article, enable lazy loading to avoid resource blocking issues.

<picture class="object-center object-cover w-full">
<source sizes="50vw" srcset="https://res.cloudinary.com/pthethanh/image/upload/v1636264048/effective-options/options-w1280.webp 1280w,https://res.cloudinary.com/pthethanh/image/upload/v1636264049/effective-options/options-w640.webp 640w,https://res.cloudinary.com/pthethanh/image/upload/v1636264049/effective-options/options-w320.webp 320w" type="image/webp">
<img decoding="async" loading="lazy" width="359" height="240" class="object-center object-cover bg-none w-full mb-2" src="https://res.cloudinary.com/pthethanh/image/upload/v1636264047/effective-options/options-worg.jpg" alt="unsplash/Victoriano Izquierdo">
</picture>

Requests Count #

Keep the number of requests from browsers to the server low and remove all the unnecessary requests. Always keep response content small to improve performance.

...to be continued...