⚡ 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.
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 →
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 .
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.
📊 Optimisation Technique Impact on PageSpeed Insights Scores
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. |
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.
🖼️ 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.
🚧 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 .
📦 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.
💾 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.
🔠 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.
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.
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 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
.
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 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 .
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,200msCPU, 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–400msProviders: 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–200msDigitalOcean, 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–80msCloudflare 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.
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.
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.
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 .
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.
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.
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
.
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.
# 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
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>
.
<!-- 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>
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.
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.
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.
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
.
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.
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.
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.
12. CSS Optimisation: Minification and Unused CSS Removal with PurgeCSS
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.
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 .
| 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. |
<!-- 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 (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.
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.
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
.
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
.
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.
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;immutabletells 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-Encodingheader 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.
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.
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
.
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
.
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
.
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 .
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.
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.
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 + deliveryThe 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 cachingConnects 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 cachingFree 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 optimisationBulk-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 maintenanceCleans 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 managementDisables 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.
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.
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.comreturns 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: bron 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"andloading="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
deferattribute -
All third-party JavaScript tags have
asyncordeferattribute - 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
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 →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 →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 →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 →