Let’s Connect
Ultimate Guide

Page Speed Optimization

Step-by-step roadmap to enhance your website's loading speed.

Last updated: 20/11/2023

Step 1 - Optimizing Images

Using The Picture Element

When incorporating images into your website, leveraging the picture element is essential for tailoring file sizes to different screen dimensions. Here's a practical example:

In this example, the first source tag addresses screens with a maximum width of 600px, loading the mobile-sized image. Screens exceeding 601px will utilize the standard-sized image. The img tag at the bottom ensures compatibility with browsers that might not fully support the picture element, incorporating lazy loading and defining width, height and an alternative image for fallback.

By implementing this approach, mobile users will experience faster page loading times with significantly smaller image files. Now, let's move on to creating appropriately sized image crops.

Cropping Your Images to Display Size

When refining your design from platforms like Figma or Penpot to the actual website, precision in image dimensions is key. By analyzing the display size, you ensure optimal visual presentation across various screens. For instance, if the image appears as 551px wide and 250px tall on the desktop, cropping it to 1102px by 500px is ideal—double the display size to accommodate diverse screens and pixel densities.

showing display size of an image

For mobile responsiveness, where the image might measure 292px by 213px, a suitable crop would be 584px by 424px. Save the mobile version with a “-m” suffix (e.g., kitchen-m.jpg) for easy identification. It's advisable to perform these crops during the site-building process to streamline the workflow.

showing mobile display size of an image

Consider the transformative impact on file size. Originally, a 4760x3173 pixel image weighed nearly 1MB. After cropping to the desktop's optimal size, it dramatically reduced to 108KB—a staggering 90% decrease. The mobile crop, further reducing file size to 52KB, reflects a 50% improvement. Embracing these practices ensures efficient loading times, particularly crucial for mobile users dealing with a fraction of the desktop's bandwidth.

Compressing Your Images

Now that we've crafted our crop, the next crucial step is compression and conversion to WEBP for optimal performance. Our top recommendation is leveraging compressor.io for seamless bulk compression and downloading of images in batches. Post-compression, our desktop image, originally at 108KB, gracefully plummeted to 52KB, marking a remarkable 51% space saving. Simultaneously, the mobile version, previously at 52KB, streamlined to an efficient 26KB, delivering a substantial 49% reduction.

home page of compressor.io

For mobile images like the one we've just enhanced, the sweet spot typically hovers between 20-40KB. While background images can afford to be a tad larger, it's imperative to cap them at 100KB. Witnessing our image shrink from a sizable 1000KB to a nimble 26KB on mobile illustrates the potency of this process. The swift loading time of the optimized image underscores the importance of applying this technique consistently across all site images. Committing to this practice guarantees maximum speed and performance for your website.

Converting your Images

Next, we proceed to transform the image into a WEBP format. While our preference is cloudconvert.com, feel free to choose the WEBP converter that aligns best with your needs. This optimization compounds the efforts invested prior to the conversion. By systematically reducing image sizes, applying compression and converting to WEBP, your images attain peak optimization, ensuring a seamless loading experience when users access your site.

Lazy Loading!

To enhance website loading efficiency, particularly for content below the initial screen view, consider implementing lazy loading for images. This technique delays the loading of images until they are just about to appear on the user's screen, conserving resources during the initial page load. It's important to note that lazy loading should be reserved for images positioned below the fold, as loading images above the fold can lead to Content Layout Shift (CLS) issues, negatively impacting page speed scores.

Implementing lazy loading is straightforward—simply add loading="lazy" to your image tags. This native browser tool requires no additional libraries or intricate JavaScript. Additionally, remember to include alt text along with height and width attributes for a comprehensive optimization approach.

Image Decoding

Consider adding the 'decoding="async"' attribute to every image tag on your website. By default, browsers load text and images simultaneously. However, with 'decoding="async"', you instruct the browser to defer image decoding, allowing other content to be displayed first. This practice enhances performance, an aspect often not emphasized in standard web development teachings. It's a valuable attribute that can significantly optimize your site's load time.

Optimizing The Landing Page Image

To optimize mobile loading times, I employ a strategy that involves creating a specialized version of the desktop image. Instead of loading the entire image on mobile, I crop out the central portion, typically around 800px wide.

home page of compressor.io

Given that mobile screens naturally cut off the left and right edges of larger images, this preemptive cropping reduces unnecessary load. The idea is to create a special crop for mobile screens, reserving the full-sized image for desktop users. This approach not only saves valuable space but also enhances loading speed, particularly on the landing page where lazy loading isn't applicable. By cropping to match the width of a phone screen with zero wastage, I ensure optimal performance. This technique isn't limited to landing pages; it can be applied to any background images that are better suited to a tall and narrow format on mobile. The key is to proactively trim excess content, rather than relying on the browser to handle the cropping, resulting in a more efficient and streamlined mobile experience.

Preloading Critical Images

Recently, I discovered a powerful technique to enhance website performance—using the preload tag for critical images. This involves placing the following code in the <head> section of your document:

The preload tag informs the browser about essential resources that should be loaded before the HTML parsing begins. I find it beneficial to apply this tag to every image crucial for the landing page, particularly those visible without scrolling. Consider incorporating it for elements like your logo. Additionally, you can extend this approach to preload fonts, a topic we'll delve into in the fonts section. This simple yet effective practice significantly improves page loading speed.

Lazy Load Background Images

Taking this step is pivotal in inching closer to achieving that flawless 100 score. While there are numerous libraries dedicated to lazy loading images set as background images in CSS, the good news is that you can accomplish this without relying on any of them. Our approach involves utilizing the picture element.

Position your picture element at the bottom of the primary container, the one slated to bear the background image. It should look something like this:

Enhance your #cta section by making it the primary container with a captivating background image. Ensure to set this container to position:relative and z-index: 1 for optimal styling. Consider assigning a class to your picture element or target it directly for flexibility. This approach allows you to incorporate beneficial attributes like lazy loading and decoding directly into the img tag, which wouldn't be feasible if the image were loaded through CSS. Additionally, take advantage of serving distinct images for mobile and desktop views.

Below is the code snippet for the picture element and the nested img tag:

We've configured the picture element to span the entire height and width of the #cta container by setting it to 100% dimensions. By positioning it absolutely, we overlay it on the container and a negative z-index ensures it stays behind the content. The image tag shares these properties but includes object-fit: cover. This property maintains proportional stretching, filling the entire picture element container seamlessly. Essentially, it replicates the behavior of the background-image property in CSS, but within the HTML structure. The end result is a seamless and responsive integration of the image into the container.

example call to action design

Moreover, we've implemented an overlay to darken the image, enhancing its visual appeal. Switching to HTML for background image inclusion, instead of CSS, offers the advantage of lazy loading and asynchronous decoding. This approach simplifies the process of image swapping, eliminating the need to navigate through the CSS sheet to adjust file paths for mobile and desktop declarations. With this method, modifications are made in one place within the HTML, streamlining the process and significantly improving performance.

These image optimizations contribute substantially to boosting page speed and achieving load times well into the 90s. But our journey towards optimization doesn't end here!

Step 2 – Optimizing your fonts

Navigating the intricacies of font optimization is a common struggle and I can empathize with the challenges I faced during my own learning journey. One aspect often overlooked in initial web development education is the optimal handling of fonts, a crucial element for page speed enthusiasts.

Don’t Use Google Fonts!

The conventional approach of hosting fonts directly from the Google Fonts CDN is losing favor, especially for those prioritizing page speed.

Enter the Google Webfonts Helper, a tool I rely on daily for font acquisition.

What sets it apart is its ability to subset fonts effectively—stripping away characters unnecessary for your site. Many fonts pack over 200 characters, featuring special symbols seldom used. However, the Latin alphabet's essential uppercase and lowercase letters, along with numbers and punctuation, typically amount to around 70 characters per font. The Google Fonts CDN, unfortunately, loads them all, contributing to unnecessary bloat. Recognizing and implementing this optimization, marked as point 1 in our font-seeking journey, significantly improves page speed and efficiency.

picture google fonts helper

By default, Latin is preselected, intelligently eliminating unnecessary elements and significantly shrinking each font file from 180KB to a mere 18KB. This results in substantial savings.

Moving to the next step at number 2, you have the option to choose the font weights and styles essential for your website. For optimal performance, my recommendation is to keep it minimal. In my web projects, I typically opt for regular, 700 (bold) and italic. Occasionally, I might include 900 (black), but seldom do I go beyond that. The rationale here is simple: the more styles you incorporate, the more you load, leading to slower load times. If you're certain that italics won't be used on your site, now or in the future, removing the italic style can significantly lighten the load.

picture google fonts helper

After choosing your desired fonts, step 3 provides you with the corresponding CSS. Simply click the "Modern Browsers" button to obtain the contemporary code for implementation. Additionally, at the bottom, you have the option to customize the file paths, ensuring alignment with your specific folder structure for all font files.

picture google fonts helper

Add the following code to your CSS stylesheet, typically a root.css file that's shared across all pages of your site. If you don't have one, consider creating it to centralize your navigation, footer, button and font styles. Personally, I place font declarations at the top. Ensure you include font-display: swap; under the font-weight property, like this:

Now, proceed to step 4: Download your chosen fonts and place them in the /fonts folder of your project. That's it! By locally hosting your fonts, you not only enhance your site's security but also improve its loading time. Plus, you'll no longer encounter render-blocking warnings for third-party scripts, at least not for Google. Enjoy the benefits of a faster and more secure website!

Preloading Your Fonts

To streamline the loading of your landing page image and logo, employ the same technique for preloading fonts. Simply copy and paste the following code into your preload section, adjusting the href attribute with the correct file path to your font file:

If your landing page primarily uses one font style (e.g., regular 400) above the fold, preload only that style. For multiple styles, create separate preload links for each font file.

Reducing font load times enhances overall site speed, often nudging your page speed score closer to 100.

Fixing Flash of Unstyled Content

Occasionally, a minor content layout shift of around .004s may occur due to the browser initially loading its system default font before switching to your @font-face fonts.

To mitigate this, set a fallback font in your font family declaration that closely matches the size and shape of your primary font.

Utilize a font style matcher to align the chosen fallback font with your custom font. Upload the font you're using from your /fonts folder on the right side and on the left, input the browser default font from the provided list, selecting the one that best matches in size.

Ensure both fonts are set to the same size, adjusting with a slider if needed. Verify that their line heights align perfectly, using a small terminal window to compare.

Everything Else

Google Analytics

Optimizing the placement of Google Analytics can significantly enhance page loading. Consider placing the Google Analytics script at the bottom of your <head> tag, just above the closing </head> tag or, alternatively, within the script tags at the bottom of your <body> tag. Placing it at the bottom ensures that everything above it loads first, preventing potential render-blocking issues. Personally, I prefer siting it above the <title> tag within the <head> section and this configuration has proven effective in preventing warnings related to third-party scripts rendering. Experiment with these placements to find what works best for your site's performance, keeping in mind that it's a balance between script execution and optimal page rendering.

Minify CSS and JS

I utilize npm sass for my projects and in my build and deploy settings, I've incorporated the --style=compressed option to minify my CSS. However, various alternatives are available for achieving this. It's crucial to ensure that minification is part of your workflow, as it significantly reduces file sizes. If you prefer a manual approach, several free online tools can help minify both CSS and JavaScript effortlessly.

Use SVG’s Wherever You Can

Opting for SVG (Scalable Vector Graphics) is my preference. I deliver them through image tags to streamline the DOM structure, enhancing manageability. This is especially beneficial for elements like social media icons, contact details (phone and email) and various card icons. Whenever possible, I recommend employing SVG graphics for their scalability and adaptability.

For further efficiency, I utilize a tool called svgomg to optimize all my SVGs. It's remarkable how this tool minimizes file sizes without compromising quality. The idea is to save every bit of space possible, ensuring that your web assets are not only visually appealing but also load swiftly.

Defer nonessential Javascript

If your JavaScript files aren't crucial for the initial page rendering, consider placing them at the bottom of the

and adding the 'defer' attribute. This ensures that they don't block the rendering process, allowing the website to load smoothly. With 'defer', these scripts will only execute after the page has loaded, preventing any delays or interruptions in the loading sequence.

Here's an example:

Remove jQuery and Other Third Party Scripts

Optimizing your website's performance and security is crucial and one effective way to achieve this is by reconsidering the use of third-party scripts like jQuery. With the advancements in JavaScript, many tasks that were previously reliant on jQuery can now be accomplished using native JavaScript. I've successfully revamped my clients' sites to eliminate jQuery, resulting in notable improvements in both page speed and security. It might be the right time for you to consider this shift if you haven't already.

Additionally, Font Awesome, while a popular choice, adds an extra layer of loading time through a CDN link. For a streamlined approach, consider opting for SVG icons from platforms like Flaticon. This not only reduces the number of external dependencies but also contributes to a significant boost in page speed. Making these adjustments aligns your site with modern web practices and enhances the overall user experience.

Prevent CSS stylesheet from render blocking

When dealing with a hefty CSS file, it can potentially cause page rendering delays and trigger warnings in Page Speed Insights, negatively impacting your score. To mitigate this, consider deferring the loading of your CSS, particularly focusing on the critical above-the-fold section. This involves isolating these crucial CSS rules into a separate file, often named "critical.css." To implement this, a small script can be embedded within the link for your primary CSS sheet, ensuring its deferred loading until the rest of the site has fully loaded. This strategic approach enhances the loading speed of the essential landing section, contributing to a more optimized and efficient web performance.

However, a potential issue arises when a user disables JavaScript in their browser. In such cases, the CSS for the entire site may fail to load because the JavaScript inside the link tag won't execute. To remedy this, we can employ a noscript tag to load the CSS sheet. Here's the solution:

This code essentially instructs the browser to load a specific stylesheet if JavaScript is disabled. When we integrate all components, the implementation should resemble the following:

This arrangement ensures that the critical.css sheet is loaded first, followed by the deferred stylesheet containing the remaining styles. The noscript tag provides a fallback for users who have JavaScript disabled. By implementing this structure, you can effectively enhance your page speed score and eliminate render-blocking issues for your CSS sheet. Simply copy and paste this code, adjusting the file paths as needed.

In my experience, achieving a commendable page speed score of 98-99 out of 100 was often met with a desire to eke out that extra point or two. It wasn't until I grasped the concept of employing critical CSS and deferring the rest that I finally hit the coveted 100. This not only elevated my page speed but also eliminated the render-blocking issue associated with my CSS sheet.

Need a Website? Let's Build It Right For Lasting Success.

Get In Touch