Tutorials

How to optimise website speed: practical techniques

· · Updated · 13 min read · 2,632 words
How to optimise website speed — practical techniques

A slow site loses visitors, Google rankings and sales. This guide shows you how to measure your current speed, identify the real bottlenecks and apply the optimisations with the biggest impact — from images to caching, from hosting to Core Web Vitals.

Does your site take more than 3 seconds to load? You're losing more than half of your potential visitors before they see anything. Website speed isn't an abstract technical issue — it's directly linked to the traffic you get from Google, your visitors' conversion rate and how professional your brand is perceived to be. This guide shows you how to measure, diagnose and fix performance problems in the most efficient way.

Transparency

This article also mentions Nalu Web Agency, which I have worked with for over 8 years. I know their work closely, which is why I mention them: bear that in mind when reading the comparison.

53%
of mobile users abandon a site that takes more than 3 seconds to load, according to Google/SOASTA data.
+7%
in conversions on average for every second cut from load time — source: Akamai.
2024
is the year Google completed the switch to mobile-first indexing: mobile speed is the main parameter for ranking.

How to measure site speed: the right tools

Before you optimise anything, you need to measure it. There are several tools for analysing a site's speed — each with a different perspective. Using them together gives you the full picture.

PageSpeed Insights: the starting point

PageSpeed Insights is Google's free tool that analyses the performance of any URL and gives a score from 0 to 100, separately for mobile and desktop, along with specific recommendations on what to optimise. The "Opportunities" section shows the improvements with the biggest estimated impact. The "Diagnostics" section details the technical problems. "Field Data" (when available) shows real performance measured from Chrome users — more reliable than lab tests for understanding the real experience.

Core Web Vitals: the metrics that matter to Google

Google measures user experience through three metrics called Core Web Vitals: LCP (Largest Contentful Paint) — the load time of the page's main element, which should be under 2.5 seconds; CLS (Cumulative Layout Shift) — measures how much elements shift during loading, which should be under 0.1; INP (Interaction to Next Paint) — responsiveness to user input, which should be under 200ms. These three values have been direct ranking factors on Google since 2021.

GTmetrix and WebPageTest for deeper analysis

GTmetrix offers detailed waterfall charts showing the order and duration of each resource's loading — useful for identifying specific blocking resources. WebPageTest lets you test from servers located in different parts of the world and with different connections (3G, 4G, fibre), giving a more realistic view of the experience of users whose connections differ from yours.

Image optimisation: the quickest win

On most websites, unoptimised images account for 50–80% of the page's total weight. Optimising images is almost always the intervention with the best effort-to-impact ratio.

The WebP format: why and how to switch

The WebP format produces images of comparable quality to JPEG and PNG but with file sizes 25–35% smaller. It's supported by all modern browsers (Chrome, Firefox, Safari, Edge). To convert existing images: Squoosh (online, free), ImageOptim (Mac, free), or WordPress plugins such as ShortPixel or Imagify that convert automatically on upload. On modern CMSs, the HTML <picture> tag with a JPG fallback ensures compatibility even with older browsers.

Correct dimensions: don't load images bigger than you need

A common mistake is loading 3000×2000 pixel images to display them in an 800×500px slot. The browser downloads the whole image and then resizes it via CSS — pure waste. Images should be resized to the maximum dimensions at which they're displayed, multiplied by 2 (for retina screens). A hero image that spans the full screen width on desktop can be 1440×810px — not 4000×2666px.

Lazy loading: load only what you need

Lazy loading delays the loading of images that are outside the user's initial viewport. It's implemented by adding loading="lazy" to the <img> tag. The technique is supported natively by all modern browsers without any extra JavaScript. Careful: do not apply lazy loading to the main image (the LCP element) — it would worsen your Core Web Vitals score instead of improving it.

Caching: serving files faster

Caching is a mechanism that saves copies of resources already downloaded so they don't have to be downloaded again on every visit. Implemented correctly, it drastically reduces load times for returning visitors and lightens the load on the server.

Browser cache: HTTP headers

The browser cache is configured through HTTP headers that tell the browser how long to keep a local copy of each type of file. Static files such as images, fonts and CSS rarely change — they can have a TTL (Time To Live) of 30–365 days. HTML files change more often — a TTL of a few minutes or no caching at all is more appropriate. On Apache servers, it's configured in the .htaccess file; on Nginx, in the server configuration.

Caching plugins for WordPress

For WordPress, the most effective caching plugins are: WP Rocket (paid, ~€50/year, the most complete), W3 Total Cache (free, powerful but complex to configure) and LiteSpeed Cache (free, excellent if your host uses LiteSpeed as its web server). A well-configured caching plugin can cut load times by 40–60% without touching a line of code.

CDN: bringing files closer to your users

A CDN (Content Delivery Network) distributes copies of the site's static files across servers located all over the world. When a user visits the site, they receive the files from the CDN server geographically closest to them — reducing latency. Cloudflare offers a free CDN that you activate by changing the domain's nameservers, and it improves performance without touching the site's code. For sites with significant traffic or an international audience, a CDN isn't optional.

CSS and JavaScript: reducing render blocking

Unoptimised CSS and JavaScript can block page rendering — the user sees a blank or partial page while the browser waits to download and process these files. It's one of the most common problems that lower the LCP score.

Minification and concatenation

Minification removes spaces, comments and line breaks from CSS and JavaScript files without changing their behaviour, reducing their size by 20–40%. Concatenation merges several files into one, reducing the number of HTTP requests. Both techniques are automated by WordPress plugins (WP Rocket, Autoptimize) or by build tools such as Webpack, Vite or Gulp.

Asynchronous loading and deferring JavaScript

By default, when the browser encounters a <script> tag in the HTML, it stops rendering the page until the JS file has been downloaded and executed — this blocks rendering. The solutions: defer downloads the file in parallel and executes it after the HTML has been parsed; async downloads and executes the file as soon as it's available, without waiting for the HTML. For almost all non-critical JavaScript, defer is the right attribute.

Removing unused CSS

WordPress themes and CSS frameworks such as Bootstrap include thousands of lines of CSS for features you probably don't use. Tools like PurgeCSS analyse the site and remove unused CSS rules, often reducing the weight of CSS files by 70–90%. On WordPress, plugins such as Asset CleanUp let you selectively disable scripts and styles on specific pages.

Optimisation led by professionals

If you've already applied the basics but the site is still slow, the problem is often architectural and needs an in-depth technical analysis. Marco Bagiacchi offers performance audits with a prioritised action plan. For an integrated approach to development and performance, Nalu Web Agency builds sites with performance in their DNA from the start.

Hosting: the overlooked foundation

You can optimise every image, minify every file and configure caching perfectly — but if the server hosting the site is slow, everything else counts for little. Hosting is the foundation of performance.

How to assess your current hosting's performance

TTFB (Time To First Byte) measures the time between the page request and the moment the browser receives the first byte of the response from the server. A TTFB under 200ms is excellent; above 600ms is a sign that the server is slow, overloaded or geographically distant. PageSpeed Insights shows the TTFB in the diagnostics section. If your TTFB is consistently high, the problem isn't the site's code — it's the server.

When to change hosting

Signs it's time to switch provider: TTFB consistently above 500ms, frequent downtime, slow or incompetent technical support, servers in countries far from your main audience (a US server for a site aimed at Italy adds 100–150ms of latency). The providers with the best performance benchmarks for the Italian market are SiteGround (EU servers, excellent TTFB), Kinsta (managed WordPress hosting on Google Cloud) and Cloudways (managed VPS on your chosen cloud provider).

Web fonts: optimising without sacrificing design

Custom web fonts improve visual identity but have a performance cost if they're not handled correctly. Loading fonts from Google Fonts or Adobe Fonts adds external HTTP requests and can cause FOUT (Flash of Unstyled Text) or CLS.

Self-hosting fonts

Hosting fonts directly on your own server removes the dependency on external servers, reduces HTTP requests and lets you take advantage of the local cache. Tools for converting and optimising fonts: Google Webfonts Helper (downloads Google fonts in optimised WOFF2 format) and the Font Squirrel Webfont Generator. The WOFF2 format offers the best compression — use it as your primary format, with WOFF as a fallback for older browsers.

Preloading critical fonts

The <link rel="preload"> tag in the <head> tells the browser to download the font before the CSS requests it, removing the delay. Use it only for critical fonts (the ones visible above the fold without scrolling) — preloading too many fonts has the opposite effect, creating bandwidth contention for the truly critical resources.

LCP: how to optimise the largest element on the page

Largest Contentful Paint (LCP) measures when the page's main element becomes visible. For most sites, this element is a hero image, a featured video or a large block of text. Optimising LCP has the most direct impact on your Core Web Vitals score.

Identifying the LCP element

Chrome DevTools (the Performance tab, then analyse the page load) highlights the LCP element with a coloured box. It's often the homepage header image or an article's featured image. Once identified, the optimisation strategy is specific to that type of element.

Optimising an LCP image

If the LCP element is an image: convert it to WebP, resize it to its exact display dimensions, add fetchpriority="high" (which tells the browser to download it before everything else), do not apply lazy loading, and consider preloading it with <link rel="preload">. Together, these four optimisations almost always bring LCP under 2.5 seconds on sites that started at 4–6 seconds.

Performance isn't a project: it's an ongoing process

A site that's optimised today can get worse tomorrow — every plugin update, every new uncompressed image, every third-party script you add gradually lowers performance. Regular monitoring is part of optimisation.

Third-party scripts: the hidden enemy of performance

Every third-party script you add to the site — Google Analytics, Facebook Pixel, chat widgets, newsletter popups, heatmap tools — has a performance cost. They aren't free: you pay for them in milliseconds of loading delay.

Auditing third-party scripts

Take an inventory of all the scripts currently installed on the site. PageSpeed Insights shows the impact of each third-party script in the "Reduce the impact of third-party code" section. Remove the scripts you don't actively use (how many heatmap tools have you installed and never looked at?). For the essential ones, load them with defer or asynchronously, and consider loading them only after user interaction (a click or scroll) instead of on page load.

Google Tag Manager: centralise to stay in control

If you use several tracking scripts, Google Tag Manager centralises their management in a single system: you add or remove scripts without touching the site's code, you can delay the loading of non-critical tags and you get full visibility of all active scripts. The trade-off: GTM itself is a script with its own weight (~28KB gzipped) — it's only worth it if you manage at least 3–4 different tags.

The complete speed optimisation checklist

High-impact optimisations — do these now
  • Convert all images to WebP and compress them under 200KB
  • Add loading="lazy" to all non-LCP images
  • Install a caching plugin (WP Rocket or LiteSpeed Cache)
  • Enable the Cloudflare CDN (free)
  • Check your TTFB and consider changing hosting if it's >500ms
Advanced optimisations — phase 2
  • Minify CSS and JavaScript
  • Add defer/async to non-critical scripts
  • Self-host fonts, with preload for the critical ones
  • Remove unused CSS with PurgeCSS
  • Audit and reduce third-party scripts

Ongoing monitoring: don't optimise just once

A site's performance degrades over time — every new plugin, every uncompressed image, every script you add gradually lowers the scores. Regular monitoring is the only way to keep your optimisations in place over time.

Automatic monitoring tools

Google Search Console shows aggregated Core Web Vitals problems based on real user data — check the report every month. Uptime Robot (free) monitors the site's availability and emails you if it goes offline. SpeedVitals and DebugBear offer automatic performance monitoring over time, with alerts when scores drop below defined thresholds.

Database and queries: optimising the WordPress back end

For WordPress sites, the database is often the hidden bottleneck nobody checks. Every page load runs dozens of SQL queries — if the database is fragmented, bloated with revisions or the queries aren't optimised, TTFB rises even with excellent hosting.

Cleaning up and optimising the WordPress database

An unmaintained WordPress database accumulates over time: post revisions (every save creates a new revision — on sites that have been active for years there can be thousands), spam comments, expired transients and abandoned auto-drafts. The WP-Optimize plugin lets you clean up these entries in one click and optimise the database tables (the equivalent of an SQL OPTIMIZE TABLE). Regular clean-ups — monthly or quarterly — keep the database lean and queries fast.

Limiting revisions in WordPress

By default, WordPress saves an unlimited number of revisions for each post. On sites with lots of content, this bloats the database unnecessarily. Add this line to the wp-config.php file to limit revisions to 3: define('WP_POST_REVISIONS', 3);. It doesn't affect editing — you can still go back to the last 3 versions — but it significantly reduces the database's size over time.

Object cache: cutting repeated queries

An object cache stores the results of the most frequent database queries in memory, avoiding re-running them on every request. On hosting that supports Redis or Memcached (SiteGround, Kinsta, Cloudways), a plugin such as Redis Object Cache can cut the number of queries per page by 40–60%. On shared hosting without Redis, page caching plugins (WP Rocket) implement a filesystem object cache that offers similar, if less powerful, benefits.

Video optimisation: the heaviest element

Videos are the heaviest elements you can put on a web page. An unoptimised video can on its own cancel out every other performance optimisation you've implemented.

Don't host videos directly on your server

Hosting video files directly on your own server and loading them with the <video> tag is almost always a mistake: the files are huge, they eat up server bandwidth, they don't adapt automatically to the user's connection and they have no dedicated CDN. The right solution is to use specialised platforms: YouTube (free, excellent for public content, but adds a branded player and suggestions), Vimeo (free basic plan, customisable player, no branding), Cloudflare Stream (paid, ideal for high-traffic sites with private videos).

Lazy loading for video embeds

Even embedding a YouTube video with an iframe has a cost: it loads dozens of Google scripts and resources even if the user never interacts with the video. The lazy facade technique replaces the iframe with a clickable preview image — the actual iframe only loads when the user clicks to play the video. On WordPress, the Lyte Embed plugin or a custom JavaScript solution cuts 400–600KB from a page with embedded video.

From theory to practice

If you want to apply this to your own project, take a look at my developer support and maintenance service: clear prices from €60/hour, a free quote and a reply within 24 hours.

Frequently asked questions

Answers to the most common questions on this topic.

The goal is an LCP (Largest Contentful Paint) under 2.5 seconds, a CLS (Cumulative Layout Shift) under 0.1 and an INP (Interaction to Next Paint) under 200ms. For total load time on mobile over a 4G connection, under 3 seconds is the minimum acceptable benchmark — under 2 seconds is excellent.
The main tool is PageSpeed Insights (pagespeed.web.dev) — free, provided by Google, it analyses both mobile and desktop and shows the Core Web Vitals. For more detailed analysis use GTmetrix (complete waterfall charts) or WebPageTest (tests from different geographical locations and connection types).
The most common causes: unoptimised images (excessive file size), too many active plugins (each plugin adds CSS and JavaScript), a heavy theme with several builder layers, slow or overloaded shared hosting, no caching configured, and third-party scripts that block rendering. An analysis with PageSpeed Insights identifies the specific problem in your case.
A caching plugin significantly improves performance for returning visitors and reduces the load on the server, but it doesn't solve structural problems such as images that are too heavy, slow hosting (high TTFB) or render-blocking JavaScript. It's one of the most effective interventions, but part of a wider strategy.
For a site whose audience is mainly in one country, the impact of a CDN is smaller than for a site with an international audience — but it's still there. Cloudflare's free plan adds automatic optimisations (Brotli compression, minification, caching of static resources) that improve performance even for users close to the origin server.
Yes, directly. Core Web Vitals (LCP, CLS, INP) have been confirmed ranking factors by Google since 2021. A site with poor Core Web Vitals can lose positions to competitors with similar content but better performance. The impact is most evident on competitive queries, where Google uses performance as a differentiating factor.
The basic optimisations (images, caching, Cloudflare) are free or almost free — they take time but have no direct cost. A complete professional optimisation (technical audit, implementation, testing) typically costs between €300 and €800 as a one-off project. WP Rocket, the most complete caching plugin for WordPress, costs about €50/year.
Every page has its own performance — Google measures Core Web Vitals on all pages that receive traffic, not just the homepage. That said, starting with the homepage and the main landing pages is the right priority: they have the biggest impact on conversions and brand impressions. Global optimisations (caching, CDN, images) apply automatically to every page.

Need help?

I can help you put what you've read in this article into practice.

Explore the service →

Latest articles

See all →

My services

All services →