If your server answers quickly but pages still feel slow, the delay is in what the browser has to download and run: images, plugin scripts, theme CSS and fonts. This guide covers those front-end fixes for WordPress theme performance, roughly in the order that saves the most time.
Hosting, server caching and Time to First Byte (TTFB) are covered separately in how to speed up WordPress with LiteSpeed server caching. If your TTFB is over 0.8 seconds, start there. No amount of front-end work makes up for a slow server.
Measure before you change anything
Run three typical pages (the home page, one post, one product or service page) through Google PageSpeed Insights and write down the mobile results:
- Largest Contentful Paint (LCP): good is 2.5 seconds or less. The LCP element is usually the hero image or the main headline.
- Interaction to Next Paint (INP): good is 200 milliseconds or less. Heavy JavaScript is the usual cause of a poor score.
- Cumulative Layout Shift (CLS): good is 0.1 or less. Images without dimensions, late fonts and ads push content around.
Below the scores, PageSpeed names the files behind each problem. Change one thing at a time and re-test, so you know what helped.
Resize and compress images
Images are usually the heaviest part of a WordPress page.
- Upload at the size you display. A 4000-pixel photo in an 800-pixel slot wastes most of its weight. WordPress generates smaller copies and offers them to the browser through
srcset, but some themes and page builders still output the full-size original. - Crop to what you show. If you only need one part of a large infographic, crop it before uploading rather than scaling the whole thing down.
- Use WebP or AVIF. WordPress has accepted WebP uploads since version 5.8 and AVIF since 6.5, as long as your server's image library supports the format. To convert an existing media library, use an image plugin such as EWWW Image Optimizer or ShortPixel.
- Don't fight over JPEG quality. WordPress already saves its generated sizes at quality 82. The bigger win is the original you upload: export it at the right dimensions first.
Lazy loading and the main image
Since WordPress 5.5, images get loading="lazy" automatically, so images further down the page wait until the visitor scrolls. Since 6.3, WordPress also adds fetchpriority="high" to the image it judges to be the main one.
The catch is the hero image. Sliders and page builders sometimes lazy-load it anyway, which delays LCP. If PageSpeed reports that the LCP image was lazily loaded, exclude that image from lazy loading in your optimisation plugin or theme settings.
Make sure every image has width and height attributes. WordPress adds them to images inserted in the editor, but images added by theme code or custom HTML often lack them, and that's a common cause of layout shift.
Embed videos instead of hosting them
Upload videos to YouTube or Vimeo and embed them. Video files are large, and a typical WordPress host isn't set up to stream them to many visitors at once.
An embed still has a cost: the player loads its scripts before anyone presses play. The fix is a placeholder that shows the thumbnail and loads the real player only on click. LiteSpeed Cache's Lazy Load Iframes setting and WP Rocket's Replace YouTube iframe with preview image option both do this.
If your design uses a muted background video, keep it short, compress it hard and give it a poster image so something shows straight away. Then check whether visitors actually engage with it. If they don't, a still image is faster.
Audit your plugins
The number of plugins matters less than what each one loads on the front end. One plugin that adds a slider script to every page costs more than five plugins that only run in the admin.
- Open a page in Chrome, press F12, go to the Network tab and reload. Filter by JS and CSS. Each file's path shows which plugin it comes from, in
/wp-content/plugins/plugin-name/. - Install Query Monitor to see the scripts and styles each page enqueues and any slow database queries. Our guide to PHP testing and profiling tools covers it in more detail.
- On a staging copy, deactivate one plugin at a time and re-test. If removing one makes a clear difference, look for a lighter plugin that does the same job.
- For plugins you need but only on a few pages, such as a contact form, an asset manager like Asset CleanUp can stop their CSS and JavaScript loading everywhere else.
Check that each plugin is compatible with your theme before you rely on it; conflicts often show up as duplicate scripts or broken layouts. If you're choosing plugins for a shop, our WooCommerce plugin shortlist is grouped by job so you can install one per need.
Check how heavy your theme is
On a staging copy, switch to a default theme such as Twenty Twenty-Five and test the same page. The difference in page weight and LCP is roughly what your theme costs.
Things that make a theme heavy:
- A bundled page builder, slider or animation library loaded on every page.
- Icon fonts loaded whole when the site uses a dozen icons.
- Several Google Fonts families and weights loaded from Google's servers.
- jQuery-dependent scripts that run on pages that don't need them.
Fonts are often the easiest fix. Use two families at most, load only the weights you use, and host them on your own server. Block themes can do this from the Font Library (added in WordPress 6.5), which downloads Google Fonts to your site. If you write your own @font-face rules, add font-display: swap so text shows while the font loads.
Block themes also help in another way: WordPress loads only the CSS for the blocks that appear on each page, rather than one stylesheet for every block. If you build with Elementor, keep an eye on how many widgets and global styles each page uses; our Elementor guide for beginners covers the settings worth changing.
Shopping for a new theme? Run its demo through PageSpeed Insights before you buy. A demo that scores poorly with demo content won't do better with yours.
Fix render-blocking CSS and JavaScript
PageSpeed lists files that block the first paint. Most are stylesheets and scripts in the page <head>.
For JavaScript in your own theme or plugin, WordPress 6.3 added a loading strategy to wp_enqueue_script(). Use defer for anything that isn't needed to show the page:
wp_enqueue_script(
'my-theme-slider',
get_template_directory_uri() . '/js/slider.js',
array(),
'1.0.0',
array(
'strategy' => 'defer',
'in_footer' => true,
)
);
For third-party scripts you can't edit, optimisation plugins such as LiteSpeed Cache, WP Rocket and Autoptimize can defer or delay them. Test forms, menus and the cart after each change, because delaying the wrong script breaks things quietly.
For CSS, the usual approach is to inline the critical CSS for the top of the page and load the rest afterwards. The same plugins can generate it, along with "remove unused CSS" features. Both can cause a flash of unstyled content or missing styles on pages the plugin didn't analyse, so check a few page types, not just the home page.
Let browsers cache static files
The page cache lives on the server. In the browser, what matters is that images, CSS, JavaScript and fonts are sent with long cache lifetimes, so repeat visitors don't download them again. If PageSpeed flags short cache lifetimes, turn on browser caching in your cache plugin or ask your host to add Cache-Control headers for static files.
Where to start
If you only have an hour, fix the main image first: right size, modern format, not lazy-loaded. Then work through the plugins, which takes longer but often finds the biggest single cost. Leave switching themes until last, because it's the most work, but if a default theme is dramatically faster than yours, that tells you where the weight is.
Written by
Hamzah Adil wrote about WordPress theme performance for the Wow Themes blog.




Comments
No comments yet.
Comments are closed on this post.