Most WordPress speed advice starts with "install an optimization plugin". That's step three. Steps one and two produce bigger gains and cost nothing.
Step 1: Upload Discipline
The single most effective change:
- Resize before uploading: 1600 px on the long edge for content images, 1920 px for full-width heroes. Camera originals at 4000+ px serve no purpose on a website.
- Compress before uploading to a sensible target (60–150 KB for content images).
- Choose the right format: JPEG/WebP for photos, PNG only for transparency and flat graphics, SVG for logos and icons where your setup allows it safely.
- Name files descriptively before upload — the filename becomes part of the URL permanently.
A plugin compressing a 6 MB upload is fixing a problem you created seconds earlier. Fixing it upstream also stops WordPress generating fifteen oversized derivatives.
Step 2: Check What the Theme Actually Requests
Open a page, inspect the largest image and compare its intrinsic size to its rendered size. If a 2048 px file renders at 640 px, your theme is requesting the wrong registered size. This is the most common WordPress performance bug and no plugin can fix it — it's a template decision.
While you're there:
- Confirm the hero image is not lazy-loaded.
- Confirm width and height attributes are present (WordPress adds them, but page builders sometimes strip them).
- Look for images loaded via CSS backgrounds in a page builder — they're invisible to the preload scanner.
Step 3: Then Use a Plugin, for the Right Things
Good optimization plugins do three useful jobs:
- Convert to WebP/AVIF and serve them with fallbacks.
- Bulk-compress the existing library — valuable precisely because past uploads were undisciplined.
- Regenerate or clean up unused registered sizes after a theme change.
Be aware that some plugins re-compress already-compressed images every time settings change, stacking artifacts. Compress once, well.
Step 4: Delivery
- A CDN in front of the site helps more than any plugin setting for a geographically spread audience.
- Cache aggressively: images are immutable in practice; long max-age with versioned filenames is safe.
- Enable lazy-loading below the fold (native in WordPress) but exclude the hero and anything in the first viewport.
Step 5: Verify
Run Lighthouse before and after, and check the specific diagnostics: "Properly size images", "Serve images in next-gen formats", "Efficiently encode images", "Largest Contentful Paint element". Then confirm with field data over the following weeks, because lab scores on your machine don't reflect a phone on mobile data.
If a change doesn't move those numbers, it isn't an optimization — it's a setting you changed.