Why your site is slow
Slow sites almost always share the same root causes. The tools differ, the symptoms are the same. I see this pattern on Magento shops, WordPress blogs, Wix sites and custom builds:
- ▸Oversized JavaScript bundles the browser must parse before anything becomes visible. Every unnecessary library adds up.
- ▸Render-blocking resources: CSS or scripts in the <head> that prevent the page from painting.
- ▸Images without compression, without WebP conversion, without correct sizing per viewport.
- ▸High TTFB (Time to First Byte) caused by a slow server, missing cache layers or a database query running on every request.
- ▸Third-party scripts that load asynchronously but still occupy the main thread: Google Tag Manager, chat widgets, consent banners, social embeds.
Most sites have three or four of these simultaneously. That is not a coincidence. Platforms like Wix and early WordPress themes were built for features, not speed. Technical debt accumulates as long as nobody actively tracks it.
What Core Web Vitals actually measure
Google measures three signals for user experience. LCP (Largest Contentful Paint) measures how quickly the largest visible element is loaded. That is almost always a hero image or a large heading. Anything above 2.5 seconds is poor. Anything above 4 seconds is very poor.
INP (Interaction to Next Paint) measures how quickly the page responds to a click or keypress. It definitively replaced First Input Delay in 2024 and is now the primary responsiveness signal. CLS (Cumulative Layout Shift) measures how stable the page is while it loads. Buttons that shift, text that jumps because an ad loaded late: those are CLS sources.
Google uses these three as ranking signals in search results. But beyond SEO: a page with an LCP of 4 seconds loses an average of 7% conversion per additional second of delay. These are not abstract statistics. Those are orders, enquiries and contact forms that never arrive.
My audit approach
A performance audit without data is guesswork. I always measure two things simultaneously: lab data and field data. Lab data comes from Lighthouse and the PSI API, run against your URL under controlled conditions. Field data comes from the Chrome User Experience Report (CrUX), the real measurements of your visitors over the past 28 days.
- ▸PSI API run on all critical pages: homepage, category page, product page, contact page. Each page separately, because problems are rarely uniform.
- ▸Network waterfall analysis in Chrome DevTools: which resource blocks what, which requests are sequential that could be parallel.
- ▸Tree-shake check on JavaScript bundles: which dependencies are loaded but partially or not used.
- ▸Image audit: format, compression ratio, dimensions versus display size, lazy load implementation.
- ▸Third-party impact measurement: how much main thread time scripts from outside your domain claim.
The result is a prioritised list of bottlenecks, sorted by impact. Not all problems carry equal weight. I start where the biggest gains are.
What I typically fix
After the audit I implement the fixes. On most sites this involves a combination of the following changes:
- ▸Next.js Image component: automatic WebP conversion, correct sizing via srcset, lazy load for off-viewport images, eager load for the LCP image.
- ▸ISR cache configuration: pages rendered and cached as static files so the server has nothing to compute per visitor.
- ▸Font-display: swap on web fonts so the page shows text while the font loads, instead of an invisible flash.
- ▸CSS blocking removal: critical CSS inline, non-critical CSS deferred or via preload with media queries.
- ▸Third-party scripts deferred: Google Analytics, GTM and consent banners loaded after first contentful paint, not before.
- ▸Preloading critical images: the LCP resource registered in the <head> so the browser fetches it earlier.
Which fixes apply depends on your stack. On a Magento installation I pull different levers than on a WordPress site or a Next.js application. The approach is always specific to what the data shows.
-- Client case
CarCare24: LCP from 14 seconds to 6.8s lab, 2.14s real visitors
CarCare24 is a Magento 2 shop with around 3,400 products on Hypernode with Cloudflare Free. Before the performance waves, PSI lab LCP on mobile was 14 to 16 seconds.
The audit surfaced three primary bottlenecks:
After nine waves covering hero image optimisation, WebP conversion, deferred third-party scripts and a custom CSP module, PSI lab LCP on mobile is 6.8 seconds. Mobile performance score in lab varies between 38 and 65 on the same day, depending on CPU throttle variance. That is normal for lab measurements. What matters: CrUX data from real visitors over 28 days shows LCP 2.14 seconds, INP 111ms, CLS 0.05. All Core Web Vitals are passing. Accessibility went from 90 to 100, Best Practices from 88 to 96, SEO 100. PSI lab simulates 4x CPU throttling and Slow 4G. That is a worst-case scenario, not representative. CrUX is what your customers experience. I optimise for the second.
What I do not do
There are shortcuts that push a Lighthouse score up without improving the user experience. I do not use them.
- ✕Preloading resources that are not on the critical path, solely to inflate the score.
- ✕Setting font-display: optional so fonts are omitted when they do not load fast enough. Scores better, looks worse.
- ✕Hiding or removing images to lower CLS without fixing the underlying cause.
- ✕Adjusting Content Security Policy headers in ways that break third-party scripts to hide their impact.
- ✕Serving a lighter page to Lighthouse bots than to real visitors. Google detects this.
A score of 100 on a page nobody visits is worthless. I optimise the pages that bring in traffic, with fixes that hold up under real users on real networks.
Tools I use
The core of my toolkit: the PSI API for reproducible lab scores on any URL, Chrome DevTools for network waterfall and main thread profiling, WebPageTest for multi-step and geographic testing, and Lighthouse CI in the build pipeline so regressions are caught early. For field data I use the CrUX dashboard and the Google Search Console Core Web Vitals report.
For Magento-specific work I also use Blackfire for PHP profiling of slow backend processes, and the Magento Performance Toolkit for load patterns. On Next.js stacks I analyse bundle output via @next/bundle-analyzer and trace server-side rendering bottlenecks with the built-in Next.js trace viewer.
Audit and optimisation engagements
A performance engagement runs in two phases. First the audit: measure, analyse, rank the bottlenecks. Then optionally the implementation: apply fixes, measure again, iterate. You can engage for audit-only or for the full trajectory.
Audit price depends on the number of pages and the stack. Magento and custom builds require more measurement points than a single Next.js site. Price is agreed after an initial exploratory call.