A 12-point website speed checklist for Indian audiences
For most sites with Indian visitors, the typical reader is on an Android phone using mobile data, not a desktop on office broadband. These twelve fixes, roughly in order of payoff, make the biggest difference for that reader, with the exact setting, command or code for each one.
Core Web Vitals: "good" means
Key takeaways
- Measure first, on a mobile profile, so you know which fix matters for your site.
- Distance is the one thing you cannot optimise away. For visitors in India, host in Mumbai or Delhi NCR.
- Page caching, correctly sized images and fewer plugins fix most slow WordPress sites before any hardware change.
- Change one thing at a time and measure again, or you will never know what worked.
What a fast website means: Core Web Vitals targets
Google's Core Web Vitals are the most useful shared definition. They are measured on real visits and judged at the 75th percentile, so three out of four page loads need to hit the target, including the ones on slow phones:
Time until the largest image or text block is painted. Poor above 4 s.
Delay between a tap or click and the screen updating. Poor above 500 ms.
How much the layout jumps around while loading. Poor above 0.25.
Behind all three sits the server response time, or time to first byte (TTFB). Around 0.8 seconds or less is a sensible target; until the first byte arrives, nothing else can start.
01Host near your audience
Light in optical fibre covers roughly 200,000 km a second. Mumbai to New York is about 12,500 km in a straight line, so a single round trip cannot take less than about 125 ms, and real cable routes are longer. A new HTTPS connection needs several round trips before the first byte of HTML arrives. Host a site for Indian visitors in the US and you can lose close to half a second on distance alone, on every new connection.
VirtualCloud web and WordPress hosting runs in Mumbai and Delhi NCR, plus Singapore, Frankfurt and New York for audiences elsewhere, and we also offer KVM VPS in Mumbai and Delhi NCR; the data centres page shows what runs where. To see where your time goes today, run this from any terminal (on Windows, replace /dev/null with NUL):
curl -o /dev/null -s -w "dns %{time_namelookup}s\nconnect %{time_connect}s\ntls %{time_appconnect}s\nttfb %{time_starttransfer}s\ntotal %{time_total}s\n" https://yourbrand.in/
If connect alone is above 0.1 s from a connection in India, the server is far away, and a free website migration can move the site closer.
02Turn on full-page caching
Without a page cache, WordPress rebuilds every page from PHP and dozens of database queries on every visit. With one, the finished HTML is stored and served straight from the web server. On LiteSpeed servers, which is what VirtualCloud hosting runs, the LiteSpeed Cache plugin does this at the server level.
How
- Plugins → Add New → install and activate LiteSpeed Cache.
- LiteSpeed Cache → Cache → set Enable Cache to On and save.
- Leave logged-in caching off. WooCommerce cart, checkout and account pages are excluded automatically.
Then confirm pages really come from the cache. Load the page twice and check the response header:
curl -sI https://yourbrand.in/ | grep -i x-litespeed-cache
# x-litespeed-cache: hit ← served from the cache
# x-litespeed-cache: miss ← built by PHP (normal on the first request)
03Run a current PHP version with OPcache
Each PHP release has made WordPress and most PHP applications noticeably quicker, and old versions stop getting security fixes: PHP 8.1 reached end of life at the end of 2025, and 8.2 receives security fixes only until 31 December 2026. Use PHP 8.3 or 8.4 if your theme and plugins support it, and test on a staging copy first.
On shared hosting, change the version in cPanel under Select PHP Version and make sure the opcache extension is ticked; our help center shows how to change PHP version. On a VPS, OPcache settings live in php.ini. These are sensible starting values for a WordPress server:
; /etc/php/8.3/fpm/conf.d/10-opcache.ini (the path varies by OS)
opcache.enable=1
opcache.memory_consumption=192
opcache.interned_strings_buffer=16
opcache.max_accelerated_files=20000
opcache.validate_timestamps=1
opcache.revalidate_freq=60
Restart PHP-FPM afterwards with sudo systemctl restart php8.3-fpm.
04Resize and convert your images
A photo straight from a phone is often 4,000 pixels wide and several megabytes, while your content column shows it at perhaps 800. That difference is downloaded on every visit, often over metered mobile data. Export images at the largest size they are displayed, convert them to WebP or AVIF, and let the browser choose the right file with srcset. Always set width and height so the layout does not jump when the image arrives.
<picture>
<source type="image/avif" srcset="/img/sofa-800.avif 800w, /img/sofa-1600.avif 1600w" sizes="(max-width: 800px) 100vw, 800px">
<img src="/img/sofa-800.webp" srcset="/img/sofa-800.webp 800w, /img/sofa-1600.webp 1600w"
sizes="(max-width: 800px) 100vw, 800px" width="800" height="533"
alt="Three-seater sofa in teal fabric">
</picture>
To convert from the command line, cwebp -q 78 -resize 1600 0 sofa.jpg -o sofa-1600.webp resizes and converts in one step. In WordPress, an image optimisation plugin can create WebP copies of your existing library automatically.
05Lazy-load below the fold, prioritise the hero
Images and embeds further down the page should wait until the reader scrolls towards them. The one image that must never wait is the hero, because it is usually the Largest Contentful Paint. Tell the browser to fetch it first, and replace heavy video embeds with a lightweight preview that loads the player on tap.
<!-- the hero image: fetch it first, never lazy-load it -->
<img src="/img/hero-1200.webp" width="1200" height="675" fetchpriority="high" alt="Our showroom in Pune">
<!-- everything further down the page -->
<img src="/img/team.webp" width="800" height="533" loading="lazy" decoding="async" alt="The support team">
<iframe src="https://www.youtube-nocookie.com/embed/VIDEO_ID" loading="lazy"
width="560" height="315" title="Product demo"></iframe>
06Load fonts deliberately
Every family and weight is another file to download. Stick to one or two families, serve WOFF2, use font-display: swap so text shows immediately in a fallback font, and preload only the main text font. If your site uses Hindi or another Indian script, note that Devanagari fonts are much larger than Latin ones. Split them with unicode-range, and browsers will download the Devanagari file only on pages that actually contain Devanagari text:
@font-face {
font-family: "Body";
src: url("/fonts/body-latin.woff2") format("woff2");
font-weight: 400 700;
font-display: swap;
unicode-range: U+0000-00FF, U+2013-2014, U+2018-201D, U+20B9; /* includes ₹ */
}
@font-face {
font-family: "Body";
src: url("/fonts/body-devanagari.woff2") format("woff2");
font-weight: 400 700;
font-display: swap;
unicode-range: U+0900-097F, U+1CD0-1CFF, U+A8E0-A8FF;
}
Add <link rel="preload" href="/fonts/body-latin.woff2" as="font" type="font/woff2" crossorigin> to the page head for the main file only.
07Run fewer, better plugins
Every active plugin can add PHP work to each request and CSS or JavaScript to each page, often on pages where it does nothing. List what is active, remove what you no longer use, and replace "do everything" plugins with one plugin per job. To find the expensive ones, install Query Monitor temporarily: it shows slow database queries and which plugin made them. Remove it when you are done.
wp plugin list --status=active --fields=name,version,update
wp plugin deactivate hello-dolly
wp plugin delete hello-dolly
08Add an object cache
A page cache only helps anonymous visitors. Logged-in customers, carts, checkouts and the admin area still run PHP and query the database every time. An object cache such as Redis keeps the results of repeated queries in memory. Redis is included on WP Pro; on a VPS you can set it up in a few commands:
sudo apt install redis-server php8.3-redis
sudo systemctl enable --now redis-server
sudo systemctl restart php8.3-fpm
wp plugin install redis-cache --activate
wp redis enable
09Clean up the database
Years of post revisions, expired transients, spam comments and options left behind by deleted plugins slow down queries. The biggest hidden cost is usually autoloaded options, which WordPress loads on every single request. Take a backup first (here is how restores work), then:
# wp-config.php: keep only the last 5 revisions of each post
define( 'WP_POST_REVISIONS', 5 );
# from the site's folder over SSH
wp transient delete --expired
wp comment delete $(wp comment list --status=spam --format=ids) --force
wp db optimize
Check the size of autoloaded options with this query in phpMyAdmin (change the wp_ prefix if yours differs). WordPress's Site Health starts warning above about 800 KB:
SELECT ROUND(SUM(LENGTH(option_value)) / 1024) AS autoload_kb
FROM wp_options
WHERE autoload IN ('yes', 'on', 'auto-on', 'auto');
10Use a CDN when your audience is spread out
If nearly all your visitors are in India and your site is hosted in Mumbai, a CDN adds less than people expect for the HTML itself. It earns its place when you also have customers in the Gulf, Europe or North America, or serve large static files. If you add one, pick a CDN with points of presence inside India, not just Singapore. Either way, let browsers keep static files for a long time, using versioned file names so updates still show up:
# .htaccess: cache static files for a year
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType image/webp "access plus 1 year"
ExpiresByType image/avif "access plus 1 year"
ExpiresByType font/woff2 "access plus 1 year"
ExpiresByType text/css "access plus 1 year"
ExpiresByType application/javascript "access plus 1 year"
</IfModule>
11Check HTTP/2, HTTP/3 and compression
HTTP/2 fetches many files over one connection; browsers only use it over HTTPS, so install free SSL and force HTTPS first. HTTP/3 runs over QUIC, which copes better with the packet loss and network switches that are normal on mobile data. Text files such as HTML, CSS and JavaScript should be compressed with Brotli or gzip. LiteSpeed supports all of these; check what your site actually negotiates:
curl -sI --http2 https://yourbrand.in/ | head -1
# HTTP/2 200
curl -sI https://yourbrand.in/ | grep -i alt-svc
# alt-svc: h3=":443"; ma=86400 ← HTTP/3 is advertised
curl -sI -H "Accept-Encoding: br, gzip" https://yourbrand.in/ | grep -i content-encoding
# content-encoding: br
12Measure with free tools, one change at a time
Use tools that show both lab tests and real-visitor data, and always test the mobile view:
- PageSpeed Insights shows field data from real Chrome users (when your site has enough traffic) alongside a lab test.
- Lighthouse in Chrome DevTools runs the same lab test locally; use the mobile setting, which simulates a mid-range phone on a slow connection.
- WebPageTest lets you pick a test location in or near India and shows the full request waterfall.
- Google Search Console has a Core Web Vitals report covering every page Google knows about.
Run each test three times and take the middle result, change one thing, then test again. Lighthouse also runs from the command line, which makes before-and-after comparisons easy:
npx lighthouse https://yourbrand.in/ --form-factor=mobile --only-categories=performance --output=html --output-path=./before.html
Mumbai and Delhi NCR regions, LiteSpeed with LSCache, PHP switching in cPanel and NVMe storage. Web hosting from ₹79/mo; Redis included on WP Pro. Prices exclude 18% GST.
The website speed checklist, on one page
Tick items off as you go. Your ticks are saved in this browser only, and the print button prints just this list.
The bottom line
Speed work pays off fastest in this order: get the server close to your readers, stop rebuilding pages that have not changed, and stop sending bytes nobody needs. Everything after that is fine-tuning. If your site still struggles once the checklist is done, that is the moment to look at more capacity; our guide to choosing between shared hosting, a VPS and a dedicated server explains how to tell. And if you would like a second pair of eyes on a slow site hosted with us, open a ticket; our support desk answers 24/7.