Core Web Vitals tell you that a page is slow. This page covers the delivery layer that usually explains why: how responses are compressed, where they are served from, which protocol carries them, what gets deferred, and whether the site was even up when the request arrived.
These are mostly configuration wins rather than code changes, which makes them the cheapest performance work available.
Compression — Brotli and Gzip
HTTP compression encodes text responses — HTML, CSS, JavaScript, JSON, SVG — into a smaller form before sending, and the browser decompresses on receipt. Two algorithms matter: Gzip (universal support, RFC 1952) and Brotli (RFC 7932), which typically achieves 15–25% better ratios than Gzip at comparable speed on static text.
Smaller responses mean fewer bytes over the wire, faster TTFB, and earlier LCP — especially on mobile and high-latency links. CPU cost on modern servers is negligible because compressed static assets can be cached.
- Enable Brotli with a Gzip fallback. Clients advertise support via
Accept-Encoding. - Pre-compress static assets at build time (
.brand.gzsiblings) so the server never compresses on the hot path. - Skip already-compressed formats. JPEG, PNG, WebP, AVIF, MP4, and WOFF2 do not benefit and just waste CPU.
- Verify by looking for
Content-Encoding: brorgzipin DevTools. - Confirm your CDN honours the encoding on cached responses and varies the cache key on
Accept-Encoding— a cache that serves Brotli to a client that cannot read it produces garbage.
CDN — Content Delivery Network
A CDN is a distributed network of edge servers that cache and serve resources from a location close to the visitor. Static assets, HTML, API responses, and increasingly edge compute all get served from whichever node is nearest.
Terminating connections at the edge reduces TTFB and shortens TLS handshakes, which improves Core Web Vitals for a global audience. CDNs also absorb traffic spikes and DDoS noise. For SEO this matters directly: crawlers see the same speed and reliability your users do.
- Set long
Cache-Controllifetimes (public, max-age=31536000, immutable) on hashed, content-addressed assets. - Use shorter TTLs plus
stale-while-revalidatefor HTML you want fresh but resilient. - Have a clear purge or surrogate-key strategy so deploys invalidate exactly the right URLs.
- Forward only the headers and cookies that actually affect the response — every extra varied header fragments your cache and drops the hit ratio.
- Enable HTTP/2 or HTTP/3 and Brotli at the edge.
HTTP/2 and HTTP/3
HTTP/2 (RFC 7540) multiplexes many requests over a single TCP connection, compresses headers with HPACK, uses binary framing, and supports stream prioritisation. It removes the per-connection bottleneck of HTTP/1.1, which matters most on pages with many small resources — fonts, icons, scripts, thumbnails.
HTTP/3 (RFC 9114) replaces TCP with QUIC, a UDP-based transport (RFC 9000) that folds transport, encryption, and multiplexing into one handshake. Crucially, QUIC removes the head-of-line blocking that still limits HTTP/2: a single lost packet no longer stalls every other request on the connection.
HTTP/3 shines on lossy or high-latency networks — mobile users on patchy 4G, Wi-Fi roaming, visitors far from your origin. Connection migration also keeps sessions alive when a device switches networks.
- Check negotiation with
curl -I --http2 https://example.com, or theProtocolcolumn in DevTools. - HTTP/2 will not negotiate over plaintext in browsers, so HTTPS is a hard prerequisite.
- For HTTP/3, confirm TLS 1.3, allow UDP/443 through any firewall, and look for the
Alt-Svc: h3=":443"response header. - Keep HTTP/2 enabled as a fallback; clients that cannot use QUIC negotiate down automatically.
- Revisit your bundling strategy. Under HTTP/2 you generally want smaller, granular files — not the megabyte sprite sheets that HTTP/1.1 rewarded.
Lazy loading
Lazy loading defers off-screen resources until the user scrolls near them. Native support is the loading="lazy" attribute on <img> and <iframe>. JavaScript can be deferred with dynamic import() and route-level code splitting, and IntersectionObserver can defer almost anything else.
Images and embedded media are usually the heaviest assets on a page. Loading them all up front wastes bandwidth on content the user may never see, and competes with the requests that actually drive LCP.
- Add
loading="lazy"to images and iframes below the fold. - Never lazy-load the hero or LCP image. That delay lands directly in your LCP. Use
fetchpriority="high"on it instead. This is the single most common lazy-loading mistake. - Set explicit
widthandheighton every image to reserve layout space and prevent CLS. - In single-page apps, split route bundles so unvisited routes do not ship on first load.
Uptime monitoring
Uptime monitoring runs automated checks — usually HTTP requests, sometimes DNS or TCP probes — at a fixed interval, and alerts when a check fails or returns an unexpected status. Synthetic checks complement field data, which only fires when real visitors happen to be present.
Undetected downtime costs revenue, ranking, and trust. Crawlers that hit repeated 5xx responses will deprioritise the URL until it returns clean. A "99.9% uptime" SLA still permits roughly 8.7 hours of outage per year, and most of that budget gets spent in a handful of long incidents — so catching an outage in the first minute is the difference between a status-page note and a postmortem.
- Probe from multiple regions so one ISP issue does not page everyone.
- Validate response bodies, not just status codes. A maintenance-mode page frequently returns a clean
200, and a status-code-only monitor will happily report an outage as healthy. - Track TTFB on the same checks. Latency creep is an early warning before hard failures.
- Monitor DNS resolution and TLS certificate expiry separately — they fail differently from origin issues, and a lapsed certificate takes a site down just as hard.
- Require 2-of-3 confirmations before paging a human, to avoid alert fatigue from transient blips.
Sitecheck includes uptime monitoring with multi-region probes and body validation, so these checks run continuously rather than being set up once and forgotten.