If you're building sites for small businesses, PageSpeed scores matter more than ever. Google uses Core Web Vitals as a ranking factor, and a 56 on mobile is quietly killing your client's SEO. Here's exactly what moved the needle for us.
1. Fix Your LCP Image First
The single biggest win on every project. Largest Contentful Paint is almost always the hero image. Two things that made an immediate difference:
- Convert to WebP. We target ~45KB desktop, ~22–28KB mobile using a
<picture>element with separatesrcsetvalues. - Add
fetchpriority="high"to the<img>tag. This tells the browser to prioritize it above everything else.
<picture>
<source srcset="hero-mobile.webp" media="(max-width: 768px)" type="image/webp">
<source srcset="hero-desktop.webp" type="image/webp">
<img src="hero-desktop.jpg" fetchpriority="high" alt="Hero image">
</picture>
Don't lazy-load your LCP image. Ever.
2. Load Your Critical CSS Synchronously
This one surprises people. We had async preload on our main stylesheet to speed up initial load — it was actually causing CLS (Cumulative Layout Shift) because the page rendered before styles applied.
The fix: load site.css as a standard synchronous stylesheet. Yes, it blocks render slightly, but it eliminates the layout shift entirely and the CLS score goes to zero.
<!-- Do this -->
<link rel="stylesheet" href="/css/site.css">
<!-- Not this for critical CSS -->
<link rel="preload" href="/css/site.css" as="style">
Reserve async preload for non-critical CSS only.
3. Defer Third-Party Scripts Aggressively
Google Analytics was costing us 0.3–0.5s on every page. We moved GA4 behind Cloudflare Zaraz with a 2-second blocking trigger — it fires after the page is interactive, not during load. Scores jumped immediately.
For anything you can't defer through a tag manager, use the defer attribute at minimum:
<script src="analytics.js" defer></script>
If it doesn't affect the visible page on load, it shouldn't block render. No exceptions.
4. Preload Your Custom Fonts
If you're self-hosting fonts (and you should be — Google Fonts adds a render-blocking request), preload them in the <head> with font-display: swap in your CSS.
<link rel="preload" href="/fonts/opensans.woff2" as="font" type="font/woff2" crossorigin>
@font-face {
font-family: 'Open Sans';
src: url('/fonts/opensans.woff2') format('woff2');
font-display: swap;
}
font-display: swap ensures text renders in a fallback font immediately while the custom font loads, eliminating invisible text flashes that tank your FCP score.
5. Enable OPcache and HTTP/2 on Your Server
Front-end optimizations only go so far. On the server side, two quick wins that most shared hosting setups miss:
- OPcache — caches compiled PHP bytecode in memory. On a PHP 8.x stack this alone can cut TTFB by 40–60ms.
- HTTP/2 — enables multiplexing so the browser loads multiple assets in parallel over a single connection instead of queuing them.
On Apache, confirm both are active:
php -i | grep opcache.enable
apache2ctl -M | grep http2
If OPcache isn't enabled, add this to your php.ini:
opcache.enable=1
opcache.memory_consumption=128
opcache.max_accelerated_files=10000
Results
Combining all five on a roofing company site: 56 → 92 mobile, 91 → 99 desktop. Core Web Vitals went all green within two weeks of Google recrawling.
These aren't tricks — they're fundamentals that get skipped when you're moving fast. Slow down on these five and your clients will notice the difference in rankings.
These are the same techniques we use on every build at Zehlm Web Development — a custom web design and SEO agency based in Morganton, NC.
Top comments (0)