
Almost no site is slow for a single reason — it is a stack of small penalties that add up: a slow Time to First Byte (TTFB) from an uncached backend, render-blocking CSS and JS that delay paint, unoptimized images that eat bandwidth, a missing caching layer that forces every request to hit PHP and the database, and no CDN to shorten the physical distance a byte has to travel.
Each of those can cost 150–800ms on its own. Stack four or five of them and you land at the 3–5 second load times most "slow" sites report. Getting under 1 second means removing each penalty one at a time, in order of impact, not throwing every optimization at the problem at once. Sites that chase the wrong fix first — minifying JS on a server with no caching, for example — often see almost no improvement, because the request was already stuck waiting on PHP and MySQL before a single kilobyte of JavaScript was even downloaded.
Measure TTFB with a single curl command before changing anything — it tells you immediately whether the problem is server-side (backend, database, missing cache) or client-side (images, JS, CSS).
A TTFB above 400ms almost always points at an uncached PHP/database request. Follow that up with a Lighthouse or WebPageTest waterfall to see which specific assets are render-blocking — that report tells you exactly which fix from this article to apply first. Pay attention to the "Connect" and "DNS" numbers too: if either is consistently over 50–100ms, DNS resolution or the lack of a CDN edge close to your visitors is adding latency the rest of this checklist won't fix on its own.
Server-side caching is the single biggest lever for TTFB because it stops every request from re-running PHP and hitting the database. On a CloudStick server, Nginx (nginx-cs) sits in front of Apache and PHP-FPM, which makes it the ideal place to serve cached pages straight from disk before Apache is ever touched.
For PHP sites, enable fastcgi_cache in the site's config under /etc/nginx-cs/extra.d/<site>.d/. For anything that queries the database heavily on every page — WooCommerce carts, dynamic dashboards, custom PHP apps — pair it with Redis as an object cache so repeated queries are served from memory instead of MariaDB. Redis is already installed system-wide on a CloudStick server, so wiring an object cache in is a matter of pointing your app's cache config at the local Redis socket rather than provisioning a separate service.
If you run WordPress, skip the manual config entirely. CloudStick's WordPress Manager has a built-in caching optimizer that turns on server-level page and object caching for a site from the dashboard, with no need to hand-edit fastcgi_cache rules or a Redis config.
Images are usually 50–70% of total page weight, so this is where the biggest byte savings live. Convert JPEG/PNG to WebP or AVIF, serve responsive sizes with a srcset, and lazy-load anything below the fold with loading="lazy". A hero image that was 1.2MB as a PNG is often under 150KB as a properly compressed WebP with no visible quality loss.
JavaScript and CSS need the same triage: minify both, remove unused CSS rules, and add defer or async to any script tag that doesn't need to block rendering. A bundler doing tree-shaking (Vite, esbuild, webpack in production mode) will usually cut JS payload by 30–50% with zero code changes on your part.
Never lazy-load your hero image or anything above the fold. Doing so delays the Largest Contentful Paint (LCP) instead of improving it, because the browser waits for the lazy-load trigger before it even starts the request.
HTTP/2 or HTTP/3 removes the head-of-line blocking that HTTP/1.1 has when a browser needs dozens of assets from the same domain, and Brotli compression typically shrinks text-based assets (HTML, CSS, JS) 15–20% smaller than gzip at the same quality level. Together they cut both round-trips and payload size without touching a single line of application code.
On CloudStick, Brotli is configured per site through ssl.conf under /etc/nginx-cs/extra.d/<site>.d/, but you don't need to touch that file directly — the dashboard exposes a per-site Brotli toggle, so enabling it is a single click instead of an SSH session and an Nginx reload.
A CDN removes the last big variable: physical distance. Once your origin is fast (cached, compressed, HTTP/2+), pushing static assets and even full HTML pages to edge nodes near each visitor removes 100–300ms of network latency that no server-side fix can touch. CloudStick's Cloudflare integration connects DNS and edge caching directly from the dashboard, so the whole setup — proxying, cache rules, DDoS protection — takes a few minutes rather than a manual DNS migration.
To confirm you've actually crossed the 1-second line, re-run the same curl command from the diagnosis step and check the total time, then run a fresh Lighthouse pass to confirm Largest Contentful Paint and Time to Interactive both sit comfortably under a second on repeat visits.
In order: fix caching first, then images and JS, then protocol/compression, then the CDN. Each step compounds on the last, and most sites reach sub-1-second load times without needing all four at maximum aggressiveness — just applied in the right order. Re-test after every single change rather than batching five fixes together; that's the only way to know which optimization actually moved the number, and which one you can safely skip on sites that don't need it.

