⚡ Technical SEO · TTFB · CDN · Render-Blocking · Images · JS · CSS · Fonts · Caching · 2026

Site Speed Optimisation Guide 2026:
Every Technique That Makes Pages Load Faster

⚡ What is site speed optimisation and why does it matter for SEO? (Direct answer)

Site speed optimisation is the engineering practice of reducing the time it takes for a web page to load, render, and become interactive — across every layer of the delivery stack: server response time (TTFB), network transfer efficiency (CDN, compression, HTTP/2), browser rendering pipeline (render-blocking resources, critical CSS, JavaScript execution), asset delivery (image format and compression, font loading), and caching (browser cache, server-side cache, CDN cache). Site speed matters for SEO because it directly feeds Google's Core Web Vitals ranking signals and indirectly affects rankings through user engagement signals that slow pages suppress — bounce rate, session depth, and conversion rate. According to Deloitte Digital's Milliseconds Make Millions study , a 0.1-second improvement in mobile load time increases retail conversion rates by 8.4%. This guide covers every layer of the speed stack with implementation code, in priority order from highest impact to lowest.

📌 Boundaries with companion guides in this Technical SEO cluster
This guide owns the engineering implementation of every speed improvement technique. Adjacent guides cover what this one explicitly excludes:
  • Core Web Vitals as Google ranking signals — LCP, INP, CLS metric definitions, Good/Needs Improvement/Poor thresholds, and the Page Experience ranking factor: Core Web Vitals Guide →
  • Reading the GSC Core Web Vitals field data report — URL groups, status interpretation, monitoring workflow: Google Search Console Guide →
  • Image alt text, filename conventions, and CLS-preventing width/height attributes as on-page elements: On-Page SEO Guide →
  • Robots.txt, crawl budget, canonical tags, and redirect chain management: Technical SEO Guide →
53% Of mobile users abandon a page that takes over 3 seconds to load Source: Think with Google / SOASTA, 2017
8.4% Retail conversion rate increase per 0.1s of mobile load time improvement Source: Deloitte Digital — Milliseconds Make Millions
~54% Of mobile origins now pass all Core Web Vitals — up from 39% in 2022 Source: HTTP Archive Web Almanac 2024

1. How Site Speed Affects SEO and the Five-Layer Stack

Site speed influences SEO through two compounding mechanisms: direct ranking signal impact through Core Web Vitals, and indirect impact through user engagement signals that fast pages improve and slow pages suppress. Google confirmed Core Web Vitals as a ranking signal with the Page Experience update in June 2021, documented in Google's Page Experience documentation .

CWV Guide boundary — what belongs in this guide vs the companion guide: The Core Web Vitals Guide covers what LCP, INP, and CLS are as ranking metrics — their definitions, Google's Good/Needs Improvement/Poor thresholds, how field data is collected from Chrome users, and how the Page Experience ranking factor works. This guide covers the engineering techniques that produce better scores across all those metrics — and many additional speed dimensions beyond the three CWV metrics. Read both together for the complete picture.

The speed stack spans five distinct layers. Understanding which layer a problem originates in is the prerequisite for selecting the right fix — treating a TTFB problem with JavaScript minification produces no improvement, just as treating a render-blocking problem with a CDN does nothing. I have seen teams spend weeks optimising JavaScript bundles on sites running on shared hosting with 900ms TTFB. The infrastructure layer must come first.

🧑‍💻 From the field — Rohit Sharma, Technical SEO Specialist The audit starting point that changes everything: When I take on a new site speed engagement, the first thing I do is open PageSpeed Insights for the homepage and three representative inner pages — a category page, a product/article page, and the highest-traffic landing page. I look at the field data LCP breakdown specifically: how much is TTFB, how much is resource load delay, how much is resource load duration. In about 40% of audits I run, TTFB alone accounts for more than 60% of the total LCP time. Those sites need a CDN and full-page caching before anything else — no amount of image compression or JavaScript splitting will compensate for a 700ms server response. Identifying the dominant bottleneck layer in the first 15 minutes determines the entire project roadmap.

📊 Optimisation Technique Impact on PageSpeed Insights Scores

Hosting upgrade (shared → cloud/managed)
Highest impact
Server-side full-page caching
Very high
Image format conversion (JPEG → WebP/AVIF)
Very high
Render-blocking CSS/JS elimination
Very high
CDN deployment for static assets
High
Brotli/Gzip compression enablement
High
Image lazy loading (below-fold)
Medium-high
JavaScript minification + unused JS removal
Medium
Font loading optimisation
Medium
HTTP/2 protocol upgrade
Contextual

Impact ratings reflect typical PageSpeed Insights score improvements for sites starting from average optimisation, drawn from patterns observed across 150+ client audits. Actual gains vary widely by baseline. Source: practitioner analysis by Rohit Sharma, IndexCraft, 2024–2026.

2. Speed Testing Tools: PageSpeed Insights, Lighthouse, WebPageTest and GTmetrix

Effective speed optimisation requires understanding what each tool measures and what type of data it produces. Using the wrong tool for the wrong question — or misreading lab simulation data as real-user field data — produces misprioritised effort and false confidence.

Tool Data Type Best Used For Key Limitation
PageSpeed Insights
pagespeed.web.dev
Lab data (Lighthouse) + Field data (Chrome UX Report) for the same URL Primary tool for CWV monitoring — shows both the simulated Lighthouse score AND real Chrome user field data for LCP, INP, CLS on the same page. The field data section is Google's actual assessment of how real users experience your page. Start every audit here. Field data requires sufficient traffic — low-traffic pages show no field data. Lab score is a single throttled mobile simulation and varies between runs.
Chrome DevTools Lighthouse
DevTools → Lighthouse tab
Lab data — controlled local simulation Detailed diagnostics during development. The Opportunities and Diagnostics sections list specific actionable findings: exact render-blocking files, precise image savings by file, specific unused JavaScript by bundle name. Lab only — results vary between runs and do not represent real-user experience. Running on a fast desktop machine produces scores far higher than the throttled mobile simulation in PageSpeed Insights.
WebPageTest
webpagetest.org
Lab data from real browsers at globally distributed test locations Waterfall chart analysis — the most detailed view of how every resource loads, in what order, and what is blocking what. Essential for diagnosing complex render-blocking chains, third-party request waterfalls, and geographic TTFB variance. More complex to interpret than PageSpeed Insights; requires understanding of HTTP waterfall charts. Free tier has rate limits for API access.
GTmetrix
gtmetrix.com
Lab data with Lighthouse integration and historical tracking Before/after comparisons when validating specific optimisations. The free tier stores test history and can alert on performance regressions — useful for monitoring that a deployment hasn't introduced a speed regression. Free tier tests from a single location. Not a substitute for PageSpeed Insights field data for SEO ranking decisions.
⚠️ Lab score ≠ field data — the most critical distinction in speed work: A Lighthouse score of 95 in Chrome DevTools does not mean real users experience fast load times. Lab tests run in an isolated environment with no third-party script variability, no browser extensions, no geographic latency, and consistent simulated hardware. Field data from PageSpeed Insights (Chrome UX Report) shows the actual distribution of load times from real Chrome users on real devices. Always treat field data as the authoritative signal for SEO decisions — it is what Google's ranking systems evaluate. This distinction is documented in Google's lab vs. field data guide on web.dev .
🧑‍💻 From the field — Rohit Sharma Why I always check field data before touching anything: A SaaS client came to me in early 2025 with a Lighthouse score of 88 and a PageSpeed Insights mobile score of 82 — they genuinely believed their site was fast. When I pulled up the field data section of PageSpeed Insights, their 75th-percentile mobile LCP was 4.8 seconds — solidly "Poor." The disconnect was geographic: their team tested from Delhi on a fibre connection; their actual user base was distributed across smaller Indian cities with high 4G latency and Moto G-class devices. The lab score was irrelevant. The field data was the truth. We spent the next six weeks optimising for that audience specifically — CDN PoP coverage, TTFB reduction, image compression — and their field LCP moved to 2.1 seconds ("Good") after the 28-day CrUX window updated. Lesson: always show clients their field data before showing them lab scores.

3. The Optimisation Priority Framework — Highest Impact First

Speed optimisation is a finite-effort exercise where prioritisation determines ROI. The framework below orders techniques from highest impact per implementation hour to lowest, based on patterns observed across 150+ site audits and corroborated by impact data from the HTTP Archive Web Almanac 2024 .

🏗️ Priority 1: Infrastructure

Hosting tier, server-side caching, CDN deployment. No amount of asset optimisation compensates for a slow origin server. A 600ms TTFB on shared hosting produces worse LCP than an unoptimised page on managed cloud with 80ms TTFB. Fix the foundation first, then the assets on top of it.

Highest ROI

🖼️ Priority 2: Images

Format conversion to WebP/AVIF, compression, lazy loading, responsive srcset. Images represent 60–70% of total page weight on median web pages, per HTTP Archive 2024 Page Weight data . Format conversion produces the largest byte savings per hour of effort.

Very high ROI

🚧 Priority 3: Render-Blocking

Defer/async JavaScript, critical CSS inlining, async stylesheet loading. Render-blocking resources directly cause blank-screen time before any content appears. Eliminating them produces the most immediately visible user-experience improvement and directly raises LCP scores, per Google's render-blocking resources guide .

Very high ROI

📦 Priority 4: JavaScript

Bundle splitting, tree shaking, minification, long task elimination. Heavy JS bundles are the most common cause of poor INP scores and slow Time to Interactive. JavaScript execution blocks the main thread from responding to user input, directly degrading perceived responsiveness on mid-range mobile devices.

High ROI

💾 Priority 5: Compression & Cache

Brotli compression, Cache-Control headers, ETag configuration. Compression reduces first-visit transfer size; caching eliminates repeat downloads entirely. Together they dramatically improve repeat-visit performance — which constitutes the majority of sessions for established sites with returning audiences.

High ROI

🔠 Priority 6: Fonts & Third Parties

font-display: swap, subsetting, third-party script audit and facade loading. Impact is highly variable — a site loading 4 Google Fonts families plus 8 third-party scripts gains significantly more from this layer than a site with one self-hosted font and minimal external script load.

Contextual ROI

4. TTFB Optimisation: Server Response Time, OPcache, Redis and Full-Page Caching

Time to First Byte (TTFB) is the time elapsed between a browser sending an HTTP request and receiving the first byte of the HTML response. It is the universal prerequisite for all subsequent page loading — the browser cannot begin parsing HTML, requesting assets, or rendering content until that first byte arrives. Google recommends targeting server TTFB under 800ms, with an ideal target under 200ms, as documented in web.dev's TTFB guidance . A slow TTFB cascades through every downstream metric.

The three primary TTFB factors

1. Server-side processing time: For dynamically generated pages — WordPress, Magento, Laravel, Django — the server must execute application code, run database queries, assemble the response, and begin transmission. Without caching, every request triggers this full cycle even for pages unchanged in weeks. 2. Geographic distance: Every millisecond of network round-trip adds to TTFB. A server in Frankfurt responding to a user in Sydney experiences approximately 250–300ms of round-trip latency before any processing begins — a figure measurable with a basic ping command or WebPageTest's geographic test locations. 3. Hosting infrastructure quality: Shared hosting allocates CPU, memory, and I/O across hundreds of co-tenants — resource contention under load directly extends processing time unpredictably.

PHP OPcache — the mandatory baseline for every PHP-based site

PHP OPcache is a built-in PHP extension that caches compiled PHP bytecode in shared memory, eliminating the need to parse and compile PHP source files on every request. Without OPcache, every page request requires reading PHP files from disk, parsing them to an Abstract Syntax Tree, and compiling to executable bytecode — 10–50ms of overhead on typical production hardware per request. With OPcache properly configured, this entire cycle is eliminated for cached scripts, reducing PHP execution time by 30–70% for typical CMS workloads. Key production settings: opcache.memory_consumption=256 , opcache.max_accelerated_files=20000 , opcache.validate_timestamps=0 (disable disk checks; invalidate manually after deployments). PHP's official OPcache documentation is at php.net/manual/en/book.opcache.php .

Redis object caching — eliminating repeated database queries

Object caching stores the results of expensive database queries in Redis (an in-memory key-value store), serving subsequent requests for the same data from RAM rather than re-executing the database query. For a typical WordPress site, WP_Query calls for nav menus, widget areas, post metadata, and option values number in the dozens per page request. With Redis object caching, these results are cached after the first request and served in microseconds on all subsequent calls. Redis typically reduces TTFB by 40–150ms on database-heavy sites and reduces database server load substantially — Automattic's own infrastructure relies on Redis for WordPress.com's scale. See the Redis official documentation for configuration reference.

Full-page caching — the single highest TTFB improvement for dynamic sites

Full-page caching stores the complete assembled HTML response and serves it directly from memory or disk on subsequent requests — bypassing the entire application stack (PHP execution, database queries, template rendering). For a WordPress site without caching, a page request takes 400–800ms TTFB on a well-provisioned server. The same page served from a full-page cache takes 15–60ms. Implementation options: WP Rocket or W3 Total Cache at application layer; Varnish Cache at server layer; Cloudflare APO (Automatic Platform Optimisation) at edge — the last caches WordPress HTML at Cloudflare's global edge network for approximately $5/month, reducing TTFB from 300–600ms to 20–60ms for cached pages as benchmarked by Kinsta's Cloudflare APO benchmark analysis .

🧑‍💻 From the field — Rohit Sharma The single biggest TTFB win I've seen: In 2024, I audited a news publication on WordPress with approximately 2,000 published articles. Their average TTFB on article pages was 1.1 seconds — measured via WebPageTest from a Mumbai test node. They were on a managed WordPress host with Redis object caching already configured, but no full-page cache and no Cloudflare. We enabled Cloudflare APO. Within 24 hours, cached article page TTFB dropped to under 60ms from the Mumbai node. Their mobile LCP moved from 4.2 seconds ("Poor") to 1.9 seconds ("Good") — primarily from TTFB reduction alone, with no code or image changes. The APO subscription cost $5/month. This is why infrastructure always comes first.

5. Hosting Tier Comparison for Page Speed Performance

Hosting infrastructure is the foundation every other speed optimisation builds on. The four-tier comparison below covers realistic TTFB ranges with no caching applied — the baseline performance before any application-layer optimisation. TTFB ranges are based on measurements from WebPageTest benchmark tests and published performance data from Kinsta's WordPress hosting benchmark and Bitcatcha hosting speed research .

Shared Hosting

TTFB: 400–1,200ms

CPU, memory, and I/O shared across hundreds of sites on one server. Performance degrades unpredictably under traffic spikes from other tenants. No server configuration control. Adequate only for low-traffic static HTML sites. For any dynamic CMS with organic traffic goals: migrate immediately. Typical PageSpeed Insights mobile score on a standard WordPress install: 25–55.

Managed WordPress / Cloud Shared

TTFB: 150–400ms

Providers: Kinsta, WP Engine, Cloudways, SiteGround cloud tier. Pre-configured NGINX, PHP-FPM, Redis, and edge caching included. A practical step up for small-to-medium WordPress sites without server management overhead. Typical PageSpeed Insights mobile score: 60–80 with basic plugin optimisation.

VPS / Cloud Self-Managed

TTFB: 80–200ms

DigitalOcean, Linode, Vultr, AWS EC2, GCP Compute Engine. Full control to configure NGINX, PHP-FPM, OPcache, Redis, Brotli, HTTP/2, HTTP/3, and Varnish Cache. Best performance-per-dollar for technically capable teams. Typical PageSpeed Insights mobile score: 70–95 with full optimisation stack applied.

Edge / Serverless

TTFB: 20–80ms

Cloudflare Workers, Vercel Edge, Netlify Edge Functions, AWS Lambda@Edge. Application code executes at the CDN edge node nearest to the user, near-eliminating geographic round-trip latency. Best-in-class for JAMstack, Next.js, and API-driven architectures. Cloudflare APO approximates edge-level TTFB for WordPress via aggressive HTML edge caching.

🧑‍💻 From the field — Rohit Sharma The hosting conversation clients don't want to have: Recommending a hosting migration is the most contentious part of any speed engagement. Clients are often emotionally invested in their current host ("we've been with them for years") or reluctant to bear migration risk. My approach is to make it a data conversation. I run a WebPageTest multi-step test showing their TTFB distribution at 5, 50, and 95th percentile across 10 runs — then show them that even at the 50th percentile, their TTFB alone exceeds Google's 800ms "needs improvement" threshold. When the chart shows TTFB consuming 70% of the total LCP budget before a single asset has loaded, the hosting conversation becomes significantly easier. Data, not opinion, makes the case.

6. HTTP/2 and HTTP/3: Protocol Upgrades That Speed Up Every Request

HTTP/1.1 processes one request per TCP connection at a time. Modern pages with dozens of CSS files, JavaScript bundles, and images expose this limitation: browsers compensate by opening 6 parallel connections per domain, but each adds TCP handshake overhead and still serialises resources within each connection. Protocol upgrades are free performance gains requiring zero code changes — and they compound with every other optimisation by making all your already-optimised assets travel faster.

1
HTTP/2: multiplexing, HPACK header compression, stream prioritisation

HTTP/2 addresses HTTP/1.1's concurrency limitation through request multiplexing — sending all requests simultaneously over a single TCP connection without head-of-line blocking between streams. HPACK header compression reduces the overhead of repeated headers across many requests. HTTP/2 is supported by all modern browsers and virtually all major hosting providers and CDNs. Verify with: curl -I --http2 https://yourdomain.com — the response first line should show HTTP/2. The HTTP/2 specification and web.dev's HTTP/2 performance guide cover the full protocol details. HTTP/2 typically improves load time by 15–40% for resource-heavy pages compared to HTTP/1.1, per web.dev benchmarks.

2
HTTP/3 and QUIC: eliminating TCP transport-layer head-of-line blocking

HTTP/3 replaces TCP with QUIC — a UDP-based transport protocol originally developed by Google and standardised as RFC 9114 — as its transport layer. HTTP/2 over TCP has a fundamental weakness: when a single TCP packet is lost, all multiplexed streams on the connection wait for retransmission. QUIC handles packet loss per-stream — a dropped packet only blocks the stream that needed it. HTTP/3 produces the most significant improvements on high-latency or lossy connections: mobile networks, cross-continental connections, WiFi with interference. Supported by Chrome, Firefox, Safari, and Edge — and by NGINX (with quiche patches), Caddy, LiteSpeed, and Cloudflare. Cloudflare reports that HTTP/3 reduces connection time by 12–15% on average, with larger gains on high-latency connections, per their HTTP/3 performance analysis .

7. CDN Configuration: Edge Delivery, Cache Rules and Cache Invalidation

A Content Delivery Network distributes copies of your static assets across a global network of edge servers, serving each user from the node geographically closest to them. Round-trip latency from a user's browser to an origin server might be 180ms for an international request; from the nearest CDN edge node it drops to under 10ms. Cloudflare reports that their network covers over 320 cities globally as of 2026, per Cloudflare's network page .

1
What a CDN caches and what it cannot cache by default

Standard CDN configurations cache static assets: images, CSS, JavaScript, font files, video, PDFs, and other binary content identical for all users. Standard configurations do not cache dynamically generated HTML pages — a CMS page personalised by login state or cart contents requires per-user generation. Advanced CDN products extend caching to dynamic HTML: Cloudflare APO for WordPress caches HTML at edge nodes with intelligent cache-bypass rules for logged-in users and cart/checkout pages. Configure explicit cache rules for all static asset types with long TTLs, and verify your origin sets appropriate Cache-Control headers so the CDN knows what to store and for how long.

2
CDN selection for SEO deployments

Cloudflare free tier provides global edge delivery, DDoS protection, automatic HTTPS, HTTP/2 and HTTP/3, and Brotli compression — making it the most accessible starting point for any site. Cloudflare APO for WordPress ($5/month) adds HTML edge caching, reducing TTFB by 50–80% for cached pages. AWS CloudFront integrates natively with AWS infrastructure for custom per-path cache behaviours. Bunny.net offers excellent performance-per-dollar with a large global PoP count and straightforward pricing. Fastly supports real-time cache purge APIs and programmable VCL edge logic for complex caching requirements. For Indian-audience-heavy sites, Cloudflare and Akamai have particularly dense edge networks across Tier-2 Indian cities — measurably lower TTFB than CDNs with fewer Indian PoPs.

3
Cache invalidation: updating CDN-cached assets without serving stale files

The correct approach for long-duration caching is filename-based cache busting: include a content hash in each asset's filename ( main.a3f9d2.css rather than main.css ). When the file changes, its filename changes — making it a new URL the CDN fetches fresh from origin, while unchanged files continue serving from edge cache. Modern build tools (webpack, Vite, Parcel) generate content-hashed filenames automatically. For HTML pages without filename hashing, use the CDN's instant cache purge API to push updates when content changes. Cloudflare's Cache Purge API documentation is at developers.cloudflare.com/cache/how-to/purge-cache .

🧑‍💻 From the field — Rohit Sharma CDN PoP coverage matters more than brand name for Indian traffic: I work with a significant number of clients whose primary audience is in India — particularly in cities outside the top-tier metros. The CDN PoP count in India varies dramatically by provider: Cloudflare has nodes in Mumbai, Chennai, Delhi, Bangalore, Hyderabad, Kolkata, and several smaller cities. Some competing CDNs have only a single Mumbai node. For a user in Pune or Jaipur, that difference in edge proximity translates directly to measurable TTFB differences. When I recommend a CDN for an India-focused client, I always run WebPageTest from their primary audience cities — not just from a generic US test location — to validate CDN selection with actual latency data.

8. Gzip vs Brotli Compression: Reducing Transfer Size for All Text Assets

HTTP compression reduces the byte size of text-based assets transferred from server to browser. A 200KB JavaScript bundle compressed to 55KB with Brotli saves 145KB of transfer per page load — which at a typical mobile connection translates to 500ms–1 second of saved transfer time. Enabling compression is a single server configuration change requiring zero code modifications and zero content changes.

✅ Brotli (br) — primary algorithm

15–26% smaller than Gzip for typical web assets; 60–80% smaller than uncompressed text, per Google's original Brotli publication . Supported by all modern browsers (~97% global coverage in 2026 per Can I Use ). Use compression level 4–6 for dynamic on-the-fly compression; pre-compress static assets at level 11 during your build process for maximum savings with zero runtime CPU cost.

↩️ Gzip — essential fallback

55–75% smaller than uncompressed text. Universal support across 100% of browsers, CDNs, and proxy servers. Keep enabled as fallback — the browser's Accept-Encoding request header tells the server which algorithms it supports; the server returns the best available option automatically. Never disable Gzip when enabling Brotli — older proxy servers and some enterprise firewalls may strip Brotli encoding.

NGINX — Brotli + Gzip with correct MIME type coverage
# Requires ngx_brotli module (bundled on NGINX for most managed hosts)brotlion;
brotli_comp_level6;  # 4–6 dynamic; pre-compress statics at level 11brotli_typestext/html text/css application/javascript application/json
                  image/svg+xml font/woff2 text/xml application/xml;

# Gzip as universal fallbackgzipon;
gzip_comp_level6;
gzip_typestext/html text/css application/javascript application/json
                  image/svg+xml text/xml;
gzip_varyon; # Adds Vary: Accept-Encoding — required for correct CDN caching
⚠️ Never compress already-compressed binary formats: JPEG, WebP, AVIF, PNG, GIF, MP4, WOFF2, and ZIP files are already compressed with their own algorithms. Passing them through Gzip or Brotli adds CPU overhead and typically increases file size slightly. Configure compression directives to include only text-based MIME types: text/html , text/css , application/javascript , application/json , text/xml , and image/svg+xml .

9. Eliminating Render-Blocking Resources: CSS and JavaScript Deferral

Render-blocking resources are CSS and JavaScript files that force the browser to pause page construction until they are fully downloaded and processed. A page with three render-blocking scripts and two render-blocking stylesheets, each taking 200ms to download, shows the user a blank white screen for over 1 second before any content appears — regardless of TTFB or image optimisation quality. Google's render-blocking resources guide identifies this as one of the highest-impact improvements available on most real-world sites.

🚧 Why CSS is render-blocking

The browser must construct the complete CSS Object Model (CSSOM) before painting anything — rendering without CSS would cause a Flash of Unstyled Content as elements appear then jump to their styled positions. Any <link rel="stylesheet"> in the document head blocks all rendering until that stylesheet downloads and parses.

Fix: Inline critical above-the-fold CSS directly in the HTML head. Load the full stylesheet asynchronously using rel="preload" as="style" with an onload handler that switches it to a stylesheet.

🚧 Why JavaScript is render-blocking

Scripts without async or defer encountered in the document head force the HTML parser to stop, download the script, execute it, then continue. This is because scripts can modify the DOM — the parser cannot safely continue building the document tree while a script might be about to change it.

Fix: Add defer to first-party scripts that can run after parsing. Add async to independent third-party scripts. Move non-critical scripts to the end of <body> .

HTML — async stylesheet loading + correct script attributes
<!-- In <head>: inline critical CSS, async-load full stylesheet --><style>/* Critical CSS — only styles needed to render above-the-fold content */
  body{font-family:sans-serif;margin:0} .hero{background:#0f2744;color:#fff;padding:60px 0}
</style><!-- Async-load full stylesheet — page renders immediately, CSS loads in background --><linkrel="preload"href="/styles/main.css"as="style"onload="this.onload=null;this.rel='stylesheet'"><noscript><linkrel="stylesheet"href="/styles/main.css"></noscript><!-- Render-blocking ❌ --><scriptsrc="/js/app.js"></script><!-- Deferred ✅ — downloads in background, executes after HTML is parsed --><scriptsrc="/js/app.js"defer></script><!-- Async ✅ — for independent third-party scripts with no dependencies --><scriptsrc="https://3rdparty.com/widget.js"async></script>
🧑‍💻 From the field — Rohit Sharma Render-blocking: the fix that surprises clients the most: On a lifestyle media site I audited in 2024, their mobile PageSpeed Insights score was 34. Lighthouse flagged six render-blocking resources — four CSS stylesheets loaded synchronously in the head, and two JavaScript files without defer. Each stylesheet was from a different plugin: one from a slider, one from a social sharing widget, one from a contact form, one from an event calendar used on exactly two pages. The JavaScript files were from an analytics platform and a legacy social comment system. We removed the unused plugins (the social comment system and the event calendar from non-event pages), inlined critical CSS for the hero area, and added defer to the remaining scripts. The mobile Lighthouse score moved from 34 to 71 with those changes alone — no image compression, no CDN changes, no server work. Render-blocking removal is often the highest-leverage single action available on WordPress sites with plugin bloat.

10. Critical CSS: Inlining Above-the-Fold Styles for Instant First Paint

Critical CSS is the subset of CSS rules required to style the content visible without scrolling on initial load. Inlining it directly in the HTML <head> allows the browser to begin rendering immediately upon receiving the HTML response, without waiting for any external stylesheet to download. This technique is recommended by Google in their Extract Critical CSS guide on web.dev as a primary method to eliminate render-blocking and improve First Contentful Paint.

Three methods to extract critical CSS

Method 1 — Automated npm tooling: The critical npm package automatically extracts above-the-fold CSS for a given URL and viewport size and inlines it in the output HTML. Run as part of your build process: npx critical src/index.html --inline --width 1300 --height 900 --dest dist/index.html . Method 2 — Chrome DevTools Coverage tab: Open DevTools → More Tools → Coverage → reload the page. CSS lines highlighted in red are unused on initial load; green lines are critical CSS candidates. Export and filter manually — useful for understanding which rules are truly above-the-fold before automating. Method 3 — Lighthouse Opportunities section: The "Eliminate render-blocking resources" opportunity in Lighthouse identifies which stylesheets are blocking and how much time each adds — use this to prioritise which files to target first before investing in full critical CSS extraction.

⚠️ Critical CSS must be regenerated when the above-the-fold design changes: Critical CSS is tightly coupled to the visual design of the above-the-fold area. Redesigning the hero section, navigation, or any element visible on initial load without regenerating critical CSS will cause the inline styles to not match the rendered content, producing a Flash of Unstyled Content. Integrate critical CSS generation into your deployment pipeline so it runs automatically on every production deploy — not as a one-time manual step.

11. JavaScript Optimisation: Bundle Splitting, Tree Shaking, Minification and Long Tasks

JavaScript is the heaviest optimisation challenge in modern web performance because every kilobyte must be parsed, compiled, and executed by the browser's JavaScript engine — blocking the main thread from responding to user input during execution. According to the HTTP Archive Web Almanac 2024 JavaScript chapter , the median mobile page loads over 500KB of JavaScript (compressed), with the 90th percentile exceeding 1.4MB. A 500KB JavaScript bundle on a mid-range mobile device can block the main thread for 2–4 seconds, directly causing Poor INP scores regardless of TTFB or image quality.

1
Bundle splitting — load only the JavaScript each page actually needs

Without splitting, a page using 10% of your application's total JavaScript still downloads and parses the entire bundle on every load. With code splitting via dynamic import() (supported natively by webpack, Vite, and Rollup), route-specific components load only when that route is navigated to, and large third-party libraries (charting tools, rich text editors) load only when the component needing them is rendered. This is the most impactful JavaScript optimisation for React, Vue, Angular, or similar component-based applications — it commonly reduces initial bundle size by 40–60%, per Vite's own code splitting documentation .

2
Tree shaking — removing dead code from production bundles

Tree shaking statically analyses JavaScript imports and removes exported code not used anywhere in your application. When you import only { debounce } from lodash using ES module syntax, tree shaking ensures only the debounce function and its dependencies are included — not all 300+ lodash utilities. Tree shaking requires ES module syntax ( import/export , not CommonJS require() ) and is performed automatically by webpack in production mode, Vite, Rollup, and esbuild. Verify with webpack-bundle-analyzer or vite-bundle-visualizer — large libraries appearing in full despite partial imports indicate missing ES module support or tree shaking configuration issues.

3
Minification — removing all characters the JavaScript engine doesn't need

Minification removes whitespace, line breaks, comments, and long variable names (replaced with single-character equivalents). Modern minifiers (Terser, esbuild, SWC) also perform constant expression evaluation and dead code elimination. Minification typically reduces JavaScript size by 20–40% before compression — combined with Brotli, production JavaScript is commonly 70–85% smaller than the development source. Running un-minified JavaScript in production is never appropriate and immediately identifiable in any Lighthouse or PageSpeed Insights audit.

4
Long tasks — diagnosing and breaking up main-thread blocking work

Any JavaScript task running over 50ms is a "long task" — it blocks the main thread from responding to user input for its entire duration, directly causing Poor INP scores. Diagnose with Chrome DevTools Performance panel: record a page load and examine the Main thread row for red-capped tasks over 50ms. Common sources: large synchronous execution during initial page load, heavy third-party scripts, non-virtualised long lists rendering thousands of DOM nodes, synchronous JSON parsing of large payloads. Fixes: break long tasks using scheduler.yield() (Chrome 115+) or setTimeout(resolve, 0) to yield between work chunks; implement virtual list rendering (react-virtual, TanStack Virtual); move heavy computation to Web Workers to run off the main thread entirely. The Chrome team's Optimize Long Tasks guide on web.dev is the authoritative reference.

🧑‍💻 From the field — Rohit Sharma The JavaScript audit that exposed 200KB of unused charting library: While auditing a B2B SaaS marketing site in 2025, I ran the Chrome DevTools Coverage tab on their homepage. It showed 78% of their main JavaScript bundle was unused on initial page load — 312KB of 400KB compressed JavaScript was being downloaded but not executed until the user navigated to a specific dashboard section. The culprit was a charting library (Chart.js, loaded globally) that was only used on the dashboard route. Moving it behind a dynamic import reduced initial bundle size from 400KB to 88KB compressed. Their mobile Time to Interactive improved by 2.3 seconds and their INP moved from 340ms ("Needs Improvement") to 160ms ("Good") — from a single code-splitting change with no server or design work.

12. CSS Optimisation: Minification and Unused CSS Removal with PurgeCSS

CSS minification — automated, lossless, zero-effort in any build pipeline

CSS minification removes all whitespace, comments, and redundant syntax from CSS files without changing behaviour. A typical stylesheet minifies to 60–75% of its original size. PostCSS with cssnano, Vite, and webpack's css-minimizer-webpack-plugin all perform CSS minification automatically in production mode. Enable the production build flag and minification happens automatically — ensure development-mode unminified stylesheets are never deployed to production. This is a zero-effort, zero-risk optimisation that should be part of every build pipeline.

Unused CSS removal with PurgeCSS — eliminating framework dead weight

CSS frameworks like Bootstrap and Bulma ship complete component libraries. A site using 20% of Bootstrap components ships a 140KB minified stylesheet without PurgeCSS and a 12–20KB stylesheet after — an 85–90% size reduction for that file, per PurgeCSS documentation benchmarks . PurgeCSS analyses your HTML, JavaScript, and template files to determine which CSS selectors are actually used, then removes all others from the output. Integrate via the PostCSS plugin or webpack plugin. For Tailwind CSS, the built-in content configuration in tailwind.config.js performs the same tree-shaking automatically on every production build — no additional tool needed. The Tailwind CSS production optimisation documentation explains the built-in purge configuration in detail.

13. Image Optimisation: Format Selection, Compression, srcset, Lazy Loading and Image CDN

Images typically represent 60–70% of total page weight and are the most frequently under-optimised asset on the web, per HTTP Archive 2024 Page Weight data . Format selection, compression, responsive delivery, and loading strategy together can reduce image payload by 70–85% with no visible quality reduction — making this the consistently highest-ROI optimisation layer for content-heavy sites.

Relative file size for a typical 800×600 photograph at equivalent visual quality (JPEG = 100% baseline). Source: Google AVIF compression research, web.dev and Google WebP technical study .

AVIF
~40–50% of JPEG size
WebP
~55–70% of JPEG size
JPEG
Baseline reference (100%)
PNG
100–200%+ of JPEG size
SVG
Best for logos & icons
Format Use For Browser Support (2026) Decision Rule
WebP All photographs, screenshots, complex images ~97% globally — near universal, per Can I Use Default format for all photographic content. Replace every JPEG and PNG used for photos.
AVIF Photographs where maximum compression matters ~92% globally, per Can I Use Serve via <picture> element with WebP fallback. Do not serve as the only format.
SVG All logos, icons, illustrations, line art Universal Resolution-independent, CSS-styleable. Inline simple SVGs to eliminate the network request.
PNG Screenshots requiring pixel-perfect fidelity only Universal Avoid for photographs — files are 2–3× larger than JPEG. Use WebP with alpha channel for transparency instead.
HTML — <picture> element: AVIF → WebP → JPEG fallback with lazy loading
<!-- Above-fold LCP hero image — eager + high priority --><picture><sourcetype="image/avif"srcset="hero.avif 1x, [email protected] 2x"><sourcetype="image/webp"srcset="hero.webp 1x, [email protected] 2x"><imgsrc="hero.jpg"srcset="hero-400.jpg 400w, hero-800.jpg 800w, hero-1200.jpg 1200w"sizes="(max-width:600px) 400px, (max-width:1024px) 800px, 1200px"width="1200" height="630"alt="[Descriptive alt text]"loading="eager"fetchpriority="high"></picture><!-- Below-fold images — lazy load to defer network requests --><imgsrc="article-image.webp"width="800" height="450"alt="..."loading="lazy">
Image CDN services — on-the-fly optimisation without manual conversion

Image CDN services (Cloudinary, Imgix, Bunny.net Optimizer, Cloudflare Images) perform format conversion, compression, and responsive resizing automatically on request. You upload original high-resolution images; the image CDN serves each request with the optimal format (AVIF for supporting browsers, WebP for others), the correct dimensions for the requesting device, and the best compression level for the configured quality setting. URL parameter-based transformation syntax makes responsive image generation trivial: ?w=800&fm=webp&q=80 requests an 800px WebP at quality 80. Cloudinary's free tier allows 25 monthly credits for transformations — sufficient for most small-to-medium sites. For sites with large image libraries or frequent content updates, image CDN services eliminate the operational overhead of manual image optimisation pipelines entirely.

🧑‍💻 From the field — Rohit Sharma The image audit that found 4MB hero images on a travel site: A travel client's homepage was taking 8.1 seconds to reach LCP on mobile. The cause was embarrassingly simple: their hero carousel was cycling through five images, each a 3–4MB full-resolution JPEG exported directly from a photographer's Lightroom. These images were being served at their full 5000×3333 pixel resolution to every device — including mobile phones displaying them at 400px wide. Converting to WebP at appropriate dimensions reduced those five images from a combined 17MB to 340KB. LCP dropped from 8.1 seconds to 2.2 seconds from that single change. This is not an exceptional case — oversized uncompressed images are still among the most common root causes I find, even on professionally designed sites. The Lighthouse "Properly size images" opportunity is frequently the first thing I check.

14. Font Loading Optimisation: font-display, Preconnect, Subsetting and Self-Hosting

Web fonts cause invisible text during page load (FOIT — Flash of Invisible Text) and, for third-party font CDNs, an additional cross-origin connection that adds latency before the font request can even begin. The HTTP Archive Web Almanac 2024 Fonts chapter reports that 82% of desktop pages and 80% of mobile pages use web fonts — making font loading optimisation one of the most widely applicable performance improvements available.

1
font-display: swap — eliminate invisible text during font load

The font-display: swap declaration in @font-face rules instructs the browser to immediately render text using a system font fallback while the web font downloads, then swap the web font in when it arrives. This prevents the FOIT period where text exists in the DOM but the browser refuses to paint it while waiting for the custom font. The trade-off is a brief Flash of Unstyled Text (FOUT) — text appears in the system fallback then shifts to the web font — which is visually preferable to invisible text and significantly better for perceived load speed. For Google Fonts, append &display=swap to the font URL parameter. The full font-display specification is documented on MDN Web Docs .

2
Preconnect hints — establish connections before the font request begins

rel="preconnect" link hints establish the TCP connection, TLS handshake, and DNS lookup to a third-party domain before any request from that domain has been made. For Google Fonts, add these two tags in your HTML <head> before the Fonts link tag:
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
This eliminates 100–300ms of connection setup overhead from the critical path of the font request, per Google's font best practices guide on web.dev .

3
Self-hosting fonts — eliminating the cross-origin connection entirely

Hosting web fonts on your own domain or CDN eliminates the cross-origin connection overhead of third-party font CDNs entirely and gives you full control over Cache-Control headers. Download WOFF2 files from google-webfonts-helper or similar tools, place them in your static assets directory, and reference them via @font-face declarations in CSS. Self-hosted fonts benefit from your CDN's edge caching — returning users receive fonts from the same CDN edge as all other static assets. WOFF2 is the correct default format: universal support across all modern browsers and the most compact font format available — typically 30% smaller than WOFF for the same typeface.

4
Font subsetting — serving only the characters your site actually uses

A full Unicode web font covers thousands of characters across dozens of scripts. An English-language site needs only the Basic Latin subset: A–Z, a–z, numerals, and common punctuation. The Latin subset of a typical web font is 20–40KB versus 150–300KB for the full Unicode version — a 75–85% size reduction. Google Fonts delivers the Latin subset by default for most fonts; append &subset=latin to confirm. For self-hosted fonts, use pyftsubset (part of fonttools) or the online glyphhanger tool to generate a custom WOFF2 subset containing only the Unicode ranges present in your site's actual content.

15. Browser Caching: Cache-Control Headers, ETags and Cache Busting

Browser caching instructs the user's browser to store resource copies locally, loading them from disk on repeat visits rather than re-downloading from the server. For returning users, a well-cached site with a warm browser cache loads page resources in milliseconds — transforming repeat-visit performance regardless of server TTFB or CDN latency. The MDN HTTP Caching reference provides the authoritative specification for all Cache-Control directives.

✅ Correct caching configuration

  • Versioned static assets (CSS, JS, fonts, images): Cache-Control: public, max-age=31536000, immutable — 1 year; immutable tells browsers the file will never change at this URL
  • HTML pages: Cache-Control: no-cache — browser must revalidate with server before using cached copy
  • Filename content hashing for all versioned assets via build tooling
  • Vary: Accept-Encoding header alongside all compressed responses
  • ETag enabled on HTML — produces 304 Not Modified responses for unchanged content, saving re-download bandwidth

❌ Common caching mistakes

  • No Cache-Control headers — browser uses heuristic caching (typically minutes)
  • Short max-age on static assets (max-age=3600) — returning users re-download every hour
  • Long max-age on HTML — users receive stale page content after site updates until cache expires
  • Updating CSS/JS files without changing their filename — cached files serve old code regardless of server changes
  • Missing Vary: Accept-Encoding — CDN serves uncompressed content to browsers that requested compressed

16. Resource Hints: Preload, Prefetch, Preconnect and dns-prefetch

Resource hints are HTML link tags that communicate upcoming resource needs to the browser ahead of time, allowing it to initiate network activity earlier in the loading process. Used correctly they eliminate latency gaps in the critical rendering path; used incorrectly they compete with more important resources for bandwidth and connection slots. The full specification is maintained at the W3C Resource Hints specification .

Hint What it does When to use When NOT to use
preload
rel="preload"
Fetches the specified resource immediately at high priority, before the HTML parser would normally discover it, and stores it in cache ready for use. Critical above-fold resources discovered late: the LCP hero image referenced in CSS, the primary web font for above-fold text, a critical script loaded via JavaScript. Use as= to specify the resource type. Do not preload every image on the page — only the LCP element and above-fold images. Unused preloads waste bandwidth and trigger browser console warnings.
prefetch
rel="prefetch"
Fetches a resource at low priority for use on a future navigation, storing it in the browser cache for the next page. Resources the user is likely to need on the next navigation — the JS bundle for the most common next page, or a hero image the user will encounter on clicking a prominent CTA. Do not use for resources needed on the current page — use preload instead. Prefetch is strictly for future navigations.
preconnect
rel="preconnect"
Performs DNS lookup, TCP handshake, and TLS negotiation for the specified origin in advance — establishing the full connection before any request from that origin. Third-party origins from which the page requests resources early in load: font CDN, analytics CDN, your image CDN. Reduces connection setup overhead by 100–300ms per origin. Limit to 2–3 most critical origins. Opening preconnections to many origins simultaneously consumes socket pool slots and can delay higher-priority connections.
dns-prefetch
rel="dns-prefetch"
Performs only DNS resolution for the specified origin — lighter-weight than preconnect, with no TCP or TLS establishment. Third-party origins from which resources will be requested later in the page or on user interaction. Use as fallback alongside preconnect for older browser support. Do not use as a substitute for preconnect on origins you will request resources from in the first 500ms of page load — those warrant the full preconnect.

17. Third-Party Script Management: Audit, Async Loading and Facade Patterns

Third-party scripts — chat widgets, analytics, advertising pixels, social sharing embeds, heatmap tools — are one of the most common causes of poor page speed on otherwise well-optimised sites. They add uncontrollable network requests, CPU execution, and frequently render-blocking behaviour. According to the HTTP Archive Web Almanac 2024 Third Parties chapter , the median mobile page makes requests to 17 third-party origins — each adding DNS lookup, connection, and download overhead that falls entirely outside your control as the site owner.

1
Audit every third-party script — remove any not earning their keep

Use WebPageTest's Filmstrip View or Chrome DevTools Network panel filtered to third-party domains to enumerate every external request your pages make. For each script: Is it actively used? Does it contribute to a measurable business outcome? Has its value been validated in the last 6 months? Scripts that cannot be justified should be removed. Common candidates: abandoned analytics tags from previous tools, social sharing buttons with near-zero click rates, marketing pixel duplicates from the same vendor, outdated chat widgets for products no longer in use. Every removed script is an unconditional performance improvement — no configuration can make it as fast as not loading it at all.

2
Load all retained third-party scripts asynchronously

Every third-party script tag should have either async or defer attribute. Use async for independent scripts (analytics pixels, advertising tags) that have no dependencies on other scripts. Use defer for scripts that interact with the DOM. Never include third-party scripts synchronously in the document <head> — this is the most egregious performance anti-pattern and the most common cause of Total Blocking Time scores over 500ms, per Lighthouse's TBT diagnostic methodology documented at web.dev/tbt .

3
Interaction-triggered loading — delay non-critical scripts until engagement

For scripts that don't need to be ready on initial page load — live chat widgets, social comment systems, video embeds — delay loading entirely until the first user interaction. Listen for a scroll , click , or mousemove event to trigger script injection via a once-fired event listener. This removes these scripts from the critical loading path entirely, allowing the page to reach interactive state faster and deferring their performance cost until the user is actively engaged. The pattern is well-established and documented in Google's efficient third-party loading guide on web.dev .

4
Facade pattern — lightweight placeholders for heavy embeds

The facade pattern replaces a heavyweight third-party embed (YouTube player, Google Maps, Intercom chat widget) with a lightweight static placeholder — a screenshot or thumbnail image — that loads instantly. The real embed only loads when the user clicks the placeholder. YouTube embeds can add 400–600KB of JavaScript and multiple DNS connections per page; replacing them with a thumbnail image and click-to-load interaction reduces the associated load time from 1–2 seconds to under 50ms. The lite-youtube-embed npm package implements this for YouTube with built-in accessibility support. For chat widgets, display a styled "Start a chat" button that injects the widget script only on click — a pattern recommended by both Lighthouse and Google's Third-party facades guide on web.dev .

🧑‍💻 From the field — Rohit Sharma The third-party audit that recovered 1.4 seconds of LCP: A legal services client had a PageSpeed Insights mobile LCP of 5.8 seconds with a Lighthouse TBT of 920ms. Running WebPageTest with a network waterfall view, I could see the critical path clearly: an Intercom chat widget was injecting 680KB of JavaScript synchronously in the head — blocking everything for 1.1 seconds before the HTML parser could even begin discovering the LCP hero image. A second culprit was a Hotjar heatmap script adding another 340ms of main-thread blocking time. We implemented interaction-triggered loading for Intercom (fires on first click or scroll) and moved Hotjar to load after a 4-second setTimeout. Combined LCP improvement: 1.4 seconds from those two script management changes alone, with no other modifications. Third-party script management is always in my top five diagnostic priorities for any site with multiple external services.

18. Service Workers: Offline Caching and Repeat-Visit Performance

A service worker is a JavaScript file running in a separate browser thread that acts as a programmable proxy between your web application and the network. Service workers intercept network requests and can serve assets from a local cache — producing near-instant repeat-visit load times for cached resources even under limited connectivity. Service workers require HTTPS and same-origin hosting, as specified in the MDN Service Worker API documentation .

Cache-first strategy — the highest-impact service worker pattern for performance

A cache-first service worker strategy serves assets from the local cache if available and falls back to the network only for uncached assets. For static assets that change rarely (CSS, fonts, icons, library JavaScript), this produces instant delivery from local filesystem in microseconds. The Workbox library (by Google, documented at developer.chrome.com/docs/workbox ) simplifies service worker implementation — it provides pre-built strategies (cache-first, stale-while-revalidate, network-first) and handles cache versioning, precaching, and cache size management automatically. For most sites, a service worker implementing cache-first for static assets and stale-while-revalidate for HTML pages provides the best balance of performance and content freshness.

19. Database and Query Optimisation for CMS Sites

For CMS-based sites, database query performance is frequently the dominant TTFB contributor on cache-miss requests — first visits, authenticated users, and cache-invalidated pages. The speed of underlying database queries determines how quickly the server can assemble the HTML response when it cannot serve a cached copy. Understanding database performance is a prerequisite for any TTFB work on dynamic sites.

WordPress: diagnosing slow database queries with Query Monitor

Install the Query Monitor plugin on a staging environment to see every database query executed per page request — including query count, execution time, the calling function, and whether duplicate queries are running. A healthy WordPress page should run under 50 database queries per request. Pages running 200+ queries have significant optimisation opportunity. Common sources: unbounded WP_Query calls with no post limit, plugins querying inside loops without caching results, get_option() calls on options not loaded during WordPress bootstrap (triggering individual queries per option), and meta queries using non-indexed meta keys that force full wp_postmeta table scans. Implement Redis Object Cache to serve repeated query results from RAM rather than re-executing against the database.

MySQL/MariaDB: table optimisation and index configuration

For WordPress sites on self-managed servers, ensure database tables use the InnoDB storage engine (not MyISAM) and that key lookup columns are indexed. The most impactful indexing improvement for most WordPress sites: add an index on wp_postmeta.meta_key if post meta queries are flagged as slow by Query Monitor. Run OPTIMIZE TABLE wp_postmeta, wp_options, wp_posts monthly or after large content updates to defragment table storage and rebuild query optimiser statistics. Configure innodb_buffer_pool_size to 50–70% of available RAM on dedicated database servers — keeping frequently accessed table data in memory eliminates disk I/O for repeated query patterns. The MySQL InnoDB Buffer Pool documentation provides full configuration guidance.

20. WordPress Speed Optimisation: The Complete Plugin and Configuration Stack

WordPress powers approximately 43% of all websites globally, per W3Techs CMS market share data (updated monthly) , making it the most common platform requiring speed optimisation at scale. The plugin and configuration stack below addresses every speed layer from TTFB to asset delivery — applied in the order listed, and configured on staging before production deployment.

WP Rocket

Full-stack caching + delivery

The most comprehensive single WordPress performance plugin — handles full-page caching, GZIP/Brotli compression, render-blocking JS/CSS deferral, critical CSS generation, lazy loading, database optimisation, and CDN integration in one interface. Premium only (~$59/year as of 2026, per WP Rocket's pricing page ). Replaces most other performance plugins; the practical choice if budget allows.

Redis Object Cache

Database caching

Connects WordPress to a Redis server for persistent object cache. Caches all WP_Query, get_option(), and get_post_meta() results in Redis RAM. Requires Redis server installation (or a host that provides it). Typical TTFB reduction: 40–150ms on query-heavy sites. Free plugin, available at wordpress.org/plugins/redis-cache .

Cloudflare (free + APO)

CDN + edge caching

Free tier provides global CDN for static assets, DDoS protection, and HTTP/2 and HTTP/3. APO ($5/month per Cloudflare's APO product page ) caches HTML at Cloudflare's edge, reducing TTFB from 300–600ms to 20–60ms for cached pages. The most impactful single purchase for WordPress speed on any hosting tier.

Imagify / ShortPixel

Image optimisation

Bulk-converts the existing WordPress media library to WebP (and AVIF with Imagify), compresses at configurable quality levels, and serves WebP automatically to supporting browsers. Integrates with WordPress's picture element or .htaccess-based format switching. Essential for any site with an un-optimised image library inherited from before WebP was standard practice.

WP-Optimize

Database maintenance

Cleans WordPress database tables: removes post revisions (unlimited by default in WordPress core), spam and trashed comments, expired transients, and orphaned postmeta rows. Running a full optimisation on a mature WordPress site commonly reduces wp_posts and wp_postmeta table sizes by 50–80%, improving query performance on cache-miss requests. Free at wordpress.org/plugins/wp-optimize .

Asset CleanUp Pro

Script/style management

Disables specific CSS and JavaScript files on a per-page-type basis — removing Contact Form 7 scripts from non-contact pages, WooCommerce cart scripts from non-shop pages, etc. Addresses the plugin bloat problem where plugins load their assets globally on every page regardless of relevance — the single most effective targeted INP improvement on plugin-heavy WordPress sites.

⚠️ Plugin conflicts — configure on staging first: Running multiple WordPress performance plugins simultaneously frequently produces conflicts: two plugins both deferring the same JavaScript file, duplicate inline critical CSS injections, or competing Cache-Control header configurations. Always configure performance plugins on a staging environment, test thoroughly, and verify in PageSpeed Insights before deploying to production. If using WP Rocket, disable the performance features of all other caching plugins — WP Rocket is designed to replace, not supplement, other caching solutions.
🧑‍💻 From the field — Rohit Sharma The WordPress plugin audit that changed my onboarding process: Early in my consulting career, I would recommend performance plugins before auditing what was already running. I learned the hard way on a WooCommerce site: the client already had W3 Total Cache, Autoptimize, and a theme-bundled performance module all running simultaneously. When I added WP Rocket, the conflicts produced a site that was faster in Lighthouse but completely broken for logged-in users — cached pages were serving wrong cart data across different user sessions. That experience changed my process permanently. I now spend the first hour of every WordPress engagement doing a complete plugin inventory, disabling all performance-related plugins one by one to understand what each is doing, and starting fresh with a single chosen solution. The correct sequence is: audit → disable conflicts → configure one solution → test → deploy.

21. Performance Budgets: Setting and Enforcing Load Time Targets

A performance budget is a set of quantitative thresholds defining the maximum acceptable values for specific speed metrics or resource sizes — establishing a standard the team commits to maintaining and that automated tooling can enforce. Performance budgets prevent speed regressions: when a new feature, third-party script, or content change violates the budget, it is caught in development or CI before reaching production. The concept is documented in Google's Performance Budgets 101 guide on web.dev .

Metric Target (Good) Acceptable Budget breach action
Total page weight (mobile) < 500KB < 1MB Audit new images and assets added since last passing build; identify largest contributors and optimise or defer
JavaScript payload (compressed) < 150KB < 300KB Run bundle analyser; identify new large dependencies; implement code splitting for newly added routes
CSS payload (compressed) < 50KB < 100KB Run PurgeCSS; check for newly imported unused CSS framework components
Third-party requests < 5 per page < 10 Audit newly added scripts; identify scripts that can be self-hosted, consolidated, or removed
TTFB (server response) < 200ms < 500ms Check server-side cache hit rate; inspect new database queries added by recent code changes
PageSpeed Insights mobile score > 80 > 65 Run Lighthouse to identify top opportunities; address the highest-impact item before deployment

Budget thresholds informed by Google's Performance Budgets 101 guidance and practitioner benchmarks from 150+ site audits. Adjust based on your site's specific audience device profile and content requirements.

Enforcing performance budgets in CI/CD with Lighthouse CI

Integrate Lighthouse CI ( lhci npm package, documented at github.com/GoogleChrome/lighthouse-ci ) into your GitHub Actions, GitLab CI, or Jenkins pipeline. On every pull request, Lighthouse CI runs an audit against the built site, compares results against your configured budget thresholds, and fails the build if any threshold is exceeded. Configure .lighthouserc.json with target scores: "assertions": { "categories:performance": ["error", {"minScore": 0.80}] } . This transforms performance budgets from aspirational guidelines into mandatory deployment gates — no regression ships to production without detection. Run budget checks against a representative sample of page types (home page, category page, article page) since performance varies significantly between page templates.

22. Site Speed Optimisation Checklist

🏗️ Infrastructure & Protocol

  • Hosting tier confirmed as managed cloud or VPS minimum — shared hosting migrated away from
  • PHP OPcache enabled and configured: memory_consumption ≥128MB, validate_timestamps=0 in production
  • Redis or Memcached object caching active and connected to CMS
  • Full-page caching configured: WP Rocket, Varnish, or Cloudflare APO
  • HTTP/2 confirmed: curl -I --http2 https://yourdomain.com returns HTTP/2 in status line
  • HTTP/3 enabled if server stack supports it (NGINX with QUIC patch, LiteSpeed, or Cloudflare)
  • CDN deployed for all static assets with long-duration Cache-Control headers

📦 Compression & Caching

  • Brotli compression enabled for all text MIME types; Gzip enabled as fallback
  • Compression confirmed active: response headers show Content-Encoding: br on CSS/JS files
  • Static assets: Cache-Control: public, max-age=31536000, immutable
  • HTML pages: Cache-Control: no-cache with ETag enabled
  • Filename content hashing implemented for all versioned static assets in build pipeline
  • Vary: Accept-Encoding header present on all compressed responses

🖼️ Images

  • All photographs converted to WebP (minimum) with AVIF served via <picture> element where supported
  • All logos, icons, and line art served as SVG
  • LCP image served with fetchpriority="high" and loading="eager"
  • All below-fold images have loading="lazy"
  • Explicit width and height attributes on every image to prevent layout shift
  • Responsive srcset and sizes attributes implemented for variable-width images
  • Image compression quality validated: visually acceptable at WebP quality 75–85

🚧 Render-Blocking & JavaScript

  • Critical CSS inlined in HTML head; full stylesheet loaded asynchronously via rel="preload" + onload
  • All first-party JavaScript tags have defer attribute
  • All third-party JavaScript tags have async or defer attribute
  • JavaScript bundle split into route-specific chunks; no single initial bundle over 150KB compressed
  • Tree shaking confirmed active in production build; bundle analyser reviewed for unexpected large dependencies
  • No long tasks over 200ms in Chrome DevTools Performance panel during typical page load

🔠 Fonts & Third Parties

  • font-display: swap applied to all @font-face declarations
  • Preconnect hints in HTML head for all font CDN origins
  • Font subset confirmed: Latin-only or appropriate minimal range for site's language content
  • Third-party script audit completed: every retained script justified against a measurable business outcome
  • Heavy embeds (YouTube, Google Maps, chat widgets) implemented with facade pattern
  • Non-critical scripts delayed until user interaction event
  • PageSpeed Insights field data: check Good/Needs Improvement/Poor status for LCP, INP, CLS in the Chrome UX Report section — metric definitions and ranking signal context covered in the Core Web Vitals Guide
  • Never deploy synchronous third-party scripts in the document head without async or defer — this is the single most common source of Total Blocking Time scores over 600ms and is immediately identifiable in any Lighthouse audit

23. Frequently Asked Questions

What is TTFB and what is a good target for SEO?

TTFB (Time to First Byte) is the elapsed time between a browser requesting a page and receiving the first byte of the server's response — measuring server processing time and network latency before any content arrives. A good TTFB for SEO is under 200ms, with 800ms as the outer acceptable bound, per Google's TTFB guidance on web.dev . TTFB above 800ms cascades through every downstream metric — nothing can begin rendering until the first byte arrives. The three levers: better hosting infrastructure, server-side caching (OPcache, Redis, full-page cache), and CDN deployment to reduce geographic latency.

What are render-blocking resources and how do I eliminate them?

Render-blocking resources are CSS and JavaScript files that force the browser to pause page construction until they are fully downloaded and processed — as documented in Google's render-blocking resources guide . CSS is render-blocking by default; JavaScript without async or defer is render-blocking because it can modify the DOM. Fixes: inline critical above-the-fold CSS in the HTML head and load the full stylesheet asynchronously; add defer to all first-party scripts and async to independent third-party scripts; move non-critical scripts to the end of the body. These changes directly reduce blank-screen time before content appears and are among the highest-impact speed improvements available on most real-world sites.

What is the difference between Gzip and Brotli compression?

Both are lossless algorithms that reduce transfer size of text-based assets (HTML, CSS, JavaScript, JSON). Brotli achieves 15–26% better compression ratios than Gzip for typical web assets, per Google's original Brotli technical publication , and is supported by all modern browsers (over 97% globally in 2026, per Can I Use ). Enable Brotli as the primary algorithm with Gzip as fallback. Never compress already-compressed binary formats like JPEG, WebP, AVIF, or WOFF2 — this adds CPU overhead with no size benefit.

What image format should I use for best performance in 2026?

Use WebP as the default for all photographs and screenshots — 25–35% smaller than JPEG at equivalent quality with near-universal browser support (~97% globally per Can I Use ), corroborated by Google's WebP technical study . Use AVIF for maximum compression (40–55% smaller than JPEG per Google's AVIF research ) via the HTML picture element with WebP fallback. Use SVG for all logos, icons, and line art. Add loading="lazy" to all below-fold images and fetchpriority="high" to the above-fold LCP hero image.

How do I optimise web font loading for page speed?

Four techniques in priority order, per Google's font best practices guide : (1) Add font-display: swap to all @font-face declarations to render text immediately using a system fallback while the web font loads; (2) Add rel=preconnect hints for font CDN origins in the HTML head to establish TCP connections before the font request begins; (3) Self-host fonts on your own domain to eliminate cross-origin connection overhead entirely; (4) Subset fonts to the Unicode ranges your site actually uses, reducing file size by 60–80% for single-language sites.

How should I handle third-party scripts for page speed?

Four steps, per Google's efficient third-party loading guide : (1) Audit every third-party script and remove any not contributing a measurable business outcome — every removed script is an unconditional performance improvement; (2) Load all retained scripts with async or defer — never synchronous in the document head; (3) Delay non-critical scripts (chat widgets, social comment systems) until after the user's first interaction using a once-fired event listener; (4) Replace heavy embeds (YouTube, Google Maps, chat widgets) with lightweight facade placeholders that load the real embed only on click, as documented in Google's third-party facades guide .

How Site Speed Connects to Your Broader Technical SEO Stack

📖 Related Technical SEO & Performance Guides
Core Web Vitals · LCP · INP · CLS · Page Experience Ranking Core Web Vitals Guide: LCP, INP and CLS as Google Ranking Signals

The companion guide to this one — covering what LCP, INP, and CLS mean as ranking metrics, their Good/Needs Improvement/Poor thresholds, how field data is collected from Chrome users, and how the Page Experience ranking factor weighs them. The techniques in this guide improve those scores; the CWV guide explains the metrics and the ranking context.

Read the Core Web Vitals guide →
📊
Google Search Console · CWV Field Data Report · Monitoring Google Search Console Guide 2026: Every Report and Workflow Explained

Reading the Core Web Vitals field data report in GSC — URL group structure, Good/Needs Improvement/Poor status interpretation, and the weekly workflow for catching CWV regressions before they compound into ranking disadvantages.

Read the GSC guide →
⚙️
Technical SEO · Crawlability · Canonicals · Redirects · Robots.txt Technical SEO Guide 2026: Crawlability, Indexing and Site Architecture

The broader technical SEO guide covering robots.txt configuration, canonical tags, redirect chains, crawl budget management, and site architecture — the technical infrastructure layer that speed improvements complement but do not replace.

Read the technical SEO guide →
✏️
On-Page SEO · Image Alt Text · CLS Prevention · Filename Conventions On-Page SEO Guide: Title Tags, Meta Descriptions, Headers and Content Structure

Image alt text formulas, SEO filename conventions, and the CLS-preventing width/height attribute implementation this guide hands off — on-page image handling is in the On-Page SEO layer; image compression and format selection are in this guide.

Read the on-page SEO guide →
Your site speed action plan — implement in priority order: (1) Test your current TTFB at pagespeed.web.dev — if field data shows Poor LCP, the highest-impact first action is server-side full-page caching (install WP Rocket for WordPress, or configure Varnish + Cloudflare APO for any stack). (2) Convert your largest images to WebP using Imagify, ShortPixel, or Squoosh in batch — target every image over 100KB. (3) Open Lighthouse in Chrome DevTools and address the top item in the Opportunities section — usually render-blocking resources or unused JavaScript. These three steps address the three highest-ROI layers and typically produce 20–40 point improvements in PageSpeed Insights mobile scores on under-optimised sites, based on patterns observed across 150+ site audits at IndexCraft.
RS

Written by

Rohit Sharma

Rohit Sharma is the Technical SEO Specialist & AI Search Researcher at IndexCraft with 13+ years of experience in technical SEO, Core Web Vitals, GA4, and AI-powered search. Since Google AI Overviews launched globally in May 2024, he has tracked AI citation patterns across 47 new-site launches and conducted hands-on audits of content performance in Google AI Overviews, Perplexity AI, and ChatGPT Search. He has helped 150+ websites achieve measurable organic growth and is a recognised voice on GEO and AEO strategy in the evolving AI search landscape.

Primary sources used in this article: HTTP Archive Web Almanac 2024 · Deloitte Milliseconds Make Millions · Think with Google Mobile Speed · Google web.dev Vitals · Google Page Experience Docs · W3Techs CMS Market Share