
Image optimization, code splitting, CDN setup, and font loading strategies. Prioritized by impact.
Rank the Work Before You Do It
Most speed optimization advice is a flat list of forty tips, presented as if minifying your CSS and replacing your hosting deserve the same afternoon. They don’t. The defining feature of performance work is that the payoff curve is brutally uneven: on a typical business site, two or three categories of fix account for almost all of the improvement, and the long tail of micro-optimizations accounts for almost none of it. The skill isn’t knowing the tips — it’s knowing the order.
This guide is platform-agnostic on purpose. Whether your site runs on WordPress, Shopify, Webflow, or a custom framework, the physics are the same: bytes travel over a network, the browser parses and renders them, and JavaScript competes with the user for the device’s attention. Every technique here maps onto any stack; only the implementation details change. We’ve covered the framework-specific version for Next.js and the speed-versus-rankings question separately — this article is the general toolbox.
The impact ranking we use, built from years of client audits, goes roughly like this: images first, because they’re usually the majority of page weight and the cheapest to fix. JavaScript second, because it’s the most expensive resource per byte and the cause of nearly every interaction lag. Third-party scripts third — technically a subset of JavaScript, but practically their own beast, and the most common silent killer on otherwise well-built sites. Then fonts, then caching and CDN setup, then hosting. Each section below covers one tier: the problem, the handful of fixes that matter, and the trap people fall into instead.
Images: The Heaviest Problem and the Easiest Fix
On a typical content or marketing site, images are the largest single category of page weight — often more than everything else combined. That makes them the first stop, and fortunately the fixes are mechanical.
Start with format. Modern formats — WebP and AVIF — compress dramatically better than JPEG and PNG at equivalent visual quality, and browser support is no longer a meaningful objection. Most platforms can serve them automatically: CMS plugins, image CDNs, and framework image components all do format negotiation for you, sending AVIF or WebP to browsers that accept it and falling back otherwise. If your site is still shipping the original PNGs your designer exported, this single change can cut image weight by half or more.
Next, dimensions. The classic failure is serving one huge image to every device — a 2400-pixel-wide hero downloaded in full by a phone that will display it at 400 pixels. Responsive image markup (srcset and sizes, or your platform’s equivalent) lets the browser pick the right size for the actual viewport. Pair that with honest compression: photographic images rarely need quality settings above the 70–80 range, and the difference is invisible to everyone except the person staring at the slider.
Then, loading strategy — and this is where people overcorrect. Lazy loading below-the-fold images is free performance: the browser skips work the visitor may never scroll to. But lazy loading the hero image is one of the most common self-inflicted wounds we find in audits, because it delays the most important paint on the page behind a script that has to run first. The rule: everything below the fold loads lazily, the main above-the-fold image loads eagerly and at high priority.
Finally, always set explicit width and height (or aspect-ratio) on images. It costs nothing and eliminates the layout jumping as images pop in — the thing visitors describe as the page feeling cheap.
JavaScript: The Most Expensive Bytes You Ship
A kilobyte of JavaScript costs far more than a kilobyte of image data. The image just has to travel and decode; the JavaScript has to travel, parse, compile, and execute — on the visitor’s device, on the same main thread that’s trying to respond to their taps and scrolls. This is why a page can finish looking loaded and still feel broken: the pixels arrived, but the script is still chewing through work, and the menu won’t open until it’s done. On the mid-range phones that make up most real-world mobile traffic, the gap between your fast laptop and the actual audience is enormous.
The first fix is subtraction. Run a bundle analysis (every major build tool has one) or simply open the network panel sorted by size, and ask of each script: what does this do, and does anything still use it? Sites accumulate JavaScript the way garages accumulate boxes — a carousel library for a carousel that was removed in a redesign, a date-picker dependency imported for one admin form, an entire utility library pulled in for two functions. Deleting unused code is the only optimization with zero risk and zero maintenance cost.
The second fix is splitting and deferring. Nothing says the checkout logic must load on the homepage. Code splitting — serving each page only the scripts it actually needs — is built into modern frameworks and available via plugins on most platforms. For scripts that must be on the page but don’t need to run immediately, the defer and async attributes keep them from blocking rendering. The principle underneath both: nothing should stand between the visitor and the first paint of your content unless it’s genuinely required to produce that paint.
The trap to avoid is minification theater. Yes, minify and compress your bundles — your build tool almost certainly already does. But shaving 5% off a bundle that shouldn’t exist is effort spent on the wrong layer. Subtraction beats compression every time.
Third-Party Scripts: The Silent Killer
Here is the pattern we see more than any other in performance audits: a competently built site, reasonable images, sensible code — and a tag manager carrying years of sediment. The chat widget from a tool the company stopped paying for. Two analytics platforms measuring the same thing. A heat-mapping trial someone installed for one experiment in 2023. Pixels for ad campaigns that ended. Each one seemed weightless when it was added, because each one is just a tag. Together they routinely outweigh the site’s own JavaScript.
Third-party scripts are uniquely damaging for three reasons. They’re unaccountable: no code review approved their payload, and the vendor can change what they ship at any time without telling you. They cascade — many tags load other tags, so one innocuous-looking snippet fans out into a dozen requests you never audited. And they concentrate exactly where users feel it: on the main thread, during load and interaction, which is why third-party weight is the most common cause of pages that lag when tapped.
The fix starts with an inventory, not a tool. Open your tag manager and your page source, list every third-party script, and attach two facts to each: who owns it, and what decision its data informed in the last quarter. Anything with no owner or no decision gets removed. In our experience this conversation alone typically eliminates a third to half of the tags on a mature site — performance gained with zero development work.
For the survivors, control when they run. Analytics can load after the page is interactive. Chat widgets can load on first scroll or after a short delay rather than competing with your hero image. Heavy embeds — video players, maps, social widgets — should use the facade pattern: show a lightweight static preview, and load the real embed only when the visitor clicks. A YouTube embed loaded as a facade costs almost nothing; loaded eagerly, it can be the single heaviest thing on the page.
Fonts: Small Files, Outsized Visual Impact
Web fonts are rarely the heaviest thing on a page, but they punch above their weight because they gate the text — and text is what most visitors came for. Handled badly, fonts produce the two classic failures: invisible text while the font downloads, or a visible flash and reflow when the web font swaps in over a fallback and every line of text shifts.
The baseline fixes are quick. Use WOFF2, the universally supported modern format — if you’re serving older formats alongside it for browsers that no longer exist, you’re shipping dead weight. Self-host your fonts rather than pulling them from a third-party CDN; the extra connection setup to another domain usually costs more than it saves, and self-hosting gives you control over caching. Preload the one or two font files your above-the-fold layout depends on, so the browser fetches them immediately instead of discovering them after parsing the CSS.
Set font-display: swap (or your platform’s equivalent setting) so text renders immediately in a fallback font and upgrades when the web font arrives. The swap itself can cause layout shift, which is where fallback tuning comes in: modern CSS lets you adjust the fallback font’s metrics to closely match the web font, so the swap becomes nearly invisible. Several free tools generate these adjusted fallbacks automatically.
Then audit the menu. Every weight and style is a separate file, and design systems accumulate them — a light, two regulars from different families, a semibold, an italic nobody uses. Most sites genuinely need three or four font files; many ship eight or more. Subsetting helps too: an English-language site doesn’t need the Cyrillic and Vietnamese character ranges, and cutting them shrinks files dramatically. And consider whether some text needs a web font at all — system font stacks cost zero bytes and have quietly become respectable.
Caching and CDNs: Stop Paying for the Same Work Twice
Everything above makes the first visit faster. Caching makes every subsequent request cheaper — and for most sites it’s the most underconfigured layer of the stack, because the defaults are timid and nobody revisits them.
Browser caching is the first tier. Your static assets — images, fonts, CSS, JavaScript bundles — should be served with long cache lifetimes, on the order of months or a year, so returning visitors and visitors navigating between pages don’t re-download anything. The standard pattern that makes this safe is fingerprinted filenames: the build tool stamps a hash into each filename, so when a file changes its name changes, and the browser fetches the new one automatically. Every modern build pipeline and most platforms support this; the failure mode is simply never turning the cache headers up.
A CDN is the second tier, and at this point it’s table stakes rather than an upgrade. A content delivery network puts copies of your assets on servers near your visitors, so a request from Vancouver doesn’t travel to a data center in Virginia and back. The latency saved per request is modest; multiplied across the dozens of requests in a page load, it’s substantial — and the gap widens on mobile networks, where each round trip is more expensive. Entry-level CDN service is cheap or free, and most modern hosting includes one by default.
The third tier is the one most sites skip: caching the HTML itself. The page document usually isn’t cached at all, which means every visit waits on your server to build the page from scratch. If your pages don’t change per-visitor — and most marketing and content pages don’t — they can be cached at the CDN edge and served instantly, purged or revalidated when content changes. Page-caching plugins, edge caching, and static generation are all versions of the same idea: do the work once, serve the result many times. This single change is often what separates a server that responds in half a second from one that responds in tens of milliseconds.
Hosting and Server Response: The Floor Under Everything Else
Time to first byte — how long your server takes to start answering — is the floor under every other number. If the server takes 1.5 seconds to respond, no amount of image optimization gets the page on screen in under 1.5 seconds. The delay is inherited by everything downstream, which is why a slow origin can make a well-optimized site feel sluggish anyway.
The usual culprits, in order of frequency: overloaded shared hosting, where your site queues behind hundreds of strangers’ sites on the same machine; uncached database-driven page generation, where every visit rebuilds the page; bloated platform installations, where dozens of plugins each add queries and hooks to every request; and server locations far from the audience, which a CDN mitigates for assets but not for uncached pages. As a rough rule of thumb, a healthy server response for a typical business site is in the low hundreds of milliseconds; consistently approaching a second means the floor itself is the problem.
Two cheap wins live at this layer regardless of host. First, compression: text resources — HTML, CSS, JavaScript — should be served compressed with Brotli or gzip, which typically shrinks them by 60–80%. Most modern servers and CDNs do this by default, but it’s worth thirty seconds to verify. Second, redirect hygiene: every redirect adds a full round trip before the real page even starts loading, and chains accumulate quietly — http to https, non-www to www, old URL to new — each hop stacking on the last. Internal links should point directly at final URLs.
When the floor really is the problem, upgrading hosting is one of the rare fixes that costs money instead of time — which is exactly why it’s priced last in this list. Exhaust the free tiers first; but if your time to first byte is slow and the cache layer can’t hide it, no amount of front-end polish will compensate.
An Order of Operations You Can Actually Follow
Pulling it together into a sequence. First, measure: run your key pages through PageSpeed Insights or any reputable testing tool, on mobile settings, and identify the biggest line items — not the score, the actual breakdown of what’s heavy and what’s blocking. The score is a summary; the waterfall is the to-do list.
Then work the tiers in order. One: images — modern formats, responsive sizing, honest compression, lazy below the fold, eager hero, explicit dimensions. Two: your own JavaScript — delete what’s unused, split what’s page-specific, defer what isn’t needed for first paint. Three: third-party scripts — inventory, remove the orphans, delay the survivors, facade the heavy embeds. Four: fonts — WOFF2, self-hosted, preloaded, swap with tuned fallbacks, fewer files. Five: caching — long-lived fingerprinted assets, a CDN, and HTML cached at the edge. Six: hosting — verify compression, flatten redirects, and upgrade the origin only once the cheaper tiers are exhausted.
Two habits keep the gains from evaporating. Set a performance budget — a ceiling on page weight or load metrics that new work must fit under — because every redesign and new tool arrives with bytes attached, and sites regress by default. And re-measure on a schedule rather than after complaints; decay is gradual, and the team closest to the site is always the last to feel it.
The honest summary: speed optimization is not forty tricks, it’s six categories in descending order of payoff, and most sites get the large majority of their improvement from the first three. Do the heavy tiers properly, put a budget around the result, and don’t spend a week on micro-optimizations at the bottom of the list while a 4-megabyte hero image sits at the top of it.
Want help implementing this?
Get a free proposal for your web development setup. We’ll show you exactly where the opportunities are.
Get Free ProposalRelated Articles