Does your site take more than 3 seconds to load? You're losing more than half of your potential visitors before they see anything.
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.
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:
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.
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.
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
- 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
- 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:
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.
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.