Why Your WordPress Site Is Slow
Real data from 500+ WordPress site scans: the most common causes of slow load times, ranked by frequency and impact
Over the past two months, we've scanned over 500 WordPress sites. In this article, we break down the real causes behind slow WordPress load times. We will dive into what each issue is, why it happens, and what to do about it.
Bars scaled relative to highest frequency. Data from Metrical scan analysis, March-May 2026.
1. Your plugins have added too many stylesheets
What is the user experience?
A blank white screen for the first one to three seconds of a visit. Google's own research shows that more than half of mobile visitors abandon a page that takes longer than three seconds to load, and with this issue most of that time passes before a single pixel appears.
Why does this happen?
Every WordPress plugin installs its own styling code. WooCommerce, Elementor, Yoast SEO, Contact Form 7, WPForms, Slider Revolution, WPML: each adds at least one stylesheet, some add three or four. None of them coordinate with each other, or check whether their styles are actually needed on the page you're visiting.
Before your browser can display anything on screen, it needs two things: the page structure (your HTML) and the styling rules (your CSS). If it hasn't finished downloading every CSS file, it won't paint a single pixel.
The technical term for this is render-blocking. A site with 15–20 active plugins routinely has 12–18 separate CSS files loading in this blocking position before anything shows up. This is the most widespread issue in our data, appearing in roughly 25% of WordPress scans.
Several problems compound it:
- One file pulling from another: some stylesheets tell the browser to go fetch a second file. The browser has to wait for the first one to arrive, then go back out for the second. Each extra trip adds delay.
- Styles loading on the wrong pages: a WooCommerce stylesheet loading on a blog post, a contact form stylesheet loading on a page with no form. Each plugin loads its styles everywhere by default.
- Too many separate files: twelve separate requests is significantly slower than one or two combined, even on a fast connection.
What are some common fixes?
To see what's happening on your own site: open Chrome DevTools (F12), go to the Network tab, and filter by CSS. Each row is a stylesheet your browser had to download before it could show the page.
The CSS minification and async loading settings in WP Rocket or LiteSpeed Cache are the highest-impact toggles you can enable without touching code.
2. Your hero image is loading too late
What is the user experience?
The page layout appears with a large blank space at the top, then the image suddenly pops in. The page feels unfinished. Beyond the visitor experience, Google uses LCP as an official search ranking signal, which means a slow hero image directly suppresses where your site appears in results. LCP image problems appear in 22% of WordPress scans.
Why does this happen?
Several problems tend to stack on top of each other:
-
The image isn't marked as important.: Even with a regular image tag, the browser treats all images the same priority by default. It can't tell your hero apart from a small logo or a decorative icon below the fold. WordPress 6.3 and above does this automatically for images in the main content area, but heroes set inside page builders or theme headers are usually missed.
-
The image is too large for mobile.: Sending a 2400-pixel-wide image to a phone screen that's 390 pixels wide downloads 8–12 times more data than necessary. WordPress can create smaller versions of your images automatically, but page builders like Elementor and Divi often load the full desktop image regardless of the device.
-
The image format is outdated.: WordPress has generated WebP images on upload since version 5.8, but only for images uploaded after that upgrade. Anything older in your media library is still being served in its original format.
What are some common fixes?
A quick way to check: right-click your hero image in the browser, choose "Inspect," and look at the src attribute. If it's loading a 2400px wide file on a phone, you're transferring far more data than necessary. WP Rocket has a guide on serving WebP images in WordPress if your media library predates version 5.8.
If your hero is a CSS background, the partial workaround is adding a preload hint in the head of your theme. This tells the browser to start fetching the image early even before it processes the CSS.
WordPress has a native filter for this (wp_preload_resources) which you can use to register the image correctly, including responsive sizes and fetch priority. The proper fix is converting it to a regular image tag and marking it as high priority, which you can do in your theme or page builder template.
3. Your JavaScript is blocking user interaction
What is the user experience?
The page looks fully loaded — content is visible, layout is correct — but nothing responds. Tapping a button does nothing; clicking a menu item produces no reaction. After a second or two, it finally catches up. Most visitors don't think "this page is slow." They think the site is broken, and most don't come back.
On any action-driven page — a contact form, a product page, a booking flow, a checkout — unresponsive clicks feel broken.
Why does this happen?
JavaScript runs in a queue in your browser. When a script is running, everything else waits — including your taps and clicks. If a script takes a long time to finish (more than 50 milliseconds, which is barely perceptible to humans but significant to browsers), the page freezes for that entire duration.
Google now measures this directly. The metric is called Interaction to Next Paint (INP), and it became an official ranking factor in 2024.
Sliders, carousels, popup builders, and form plugins all run their JavaScript immediately when the page loads, regardless of whether you'll ever interact with those features. Blocking JavaScript appears in 7.4% of WordPress scans, with the highest average impact of any category we track.
What are some common fixes?
- Load scripts after the page: a defer flag on a script tells the browser "download this while the page loads, but don't run it until after everything is displayed." This removes the freeze without removing the feature. WP Rocket and LiteSpeed Cache can apply this automatically across all scripts.
- Move scripts to the bottom of the page: less precise than defer, but scripts at the bottom run after the visible content is ready rather than blocking it.
- Only load scripts when needed: the best option for sliders or popups is to not load their JavaScript at all unless the user is about to interact with them. This requires a bit more work, but it eliminates the cost entirely.
4. Your server responds slowly before anything can load
What is the user experience?
Staring at a blank browser tab with nothing happening. Someone actively clicked a link to reach your site and every extra second of delay is a chance for them to click back & choose a competitor instead.
For WooCommerce stores in particular, slow server response is one of the most direct contributors to cart abandonment, because it happens at every stage of the funnel.
Why does this happen?
Every time someone visits a WordPress page that isn't cached, the server has to build it from scratch. It loads all your active plugins, queries the database for your content, assembles everything together, and only then sends the result to the visitor.
On a default shared hosting setup with no caching, this can take 1–3 seconds. Everything else on the page waits until it's done. This appears in 17% of WordPress scans and is almost entirely absent from non-WordPress sites.
The metric for this is Time to First Byte (TTFB). This is how long from when your browser asks for a page to when the server starts answering. On a well-configured site, TTFB is under 200ms. Above 400ms and you have a server configuration problem that image compression will not fix.
The most common causes:
- No page caching: without a cache, every visitor gets a freshly built page. With one, most visitors get a pre-built copy served almost instantly.
- Slow database lookups: WordPress asks your database the same questions on every page load (site settings, menu items, widget content) instead of remembering the answers.
- WordPress running housekeeping tasks during visitor visits: WordPress handles scheduled jobs by piggybacking on real visitor requests. When a housekeeping task fires, that visitor's page load waits for it to finish.
What are some common fixes?
To check your TTFB: open DevTools, click the Network tab, reload the page, and click the first row (your HTML). The "Waiting" segment is your server response time.
- Install a page cache: WP Rocket, LiteSpeed Cache, and W3 Total Cache all work. To confirm your cache is actually serving pages (not just installed), right-click your page, choose "View Page Source," and scroll to the very bottom. You should see that a working cache plugin leaves a timestamp comment there.
- Consider a managed host: most managed WordPress hosts (WP Engine, Kinsta, Flywheel) include database memory caching by default, which handles the repeated lookup problem automatically.
- Ask your host about disabling WP-Cron: this moves WordPress's housekeeping tasks off visitor requests and onto a proper background schedule.
5. Google Fonts adds an extra request most sites haven't noticed
What is the user experience?
Text is either invisible for a noticeable moment before appearing in the correct font, or loads immediately in a generic system font and then flickers to your branded font when it arrives.
Neither is a disaster on a fast connection, but on a slow mobile connection 400–600ms of missing or flashing text is jarring enough to make a page feel unfinished. 4.3% of WordPress scans flag this as a contributing issue.
Why does this happen?
Most WordPress sites load fonts from Google's servers, not their own. That means your browser has to make extra requests to a different site before it can display your text. The chain looks like this:
- contact Google's font directory → download a CSS file → contact Google's file servers → download the actual font files.
On a slow mobile connection that round-trip adds 200–600ms before any text can appear.
While the fonts are loading, browsers handle the missing text in one of two ways. Some show a flash of invisible text where your font will be. Others show your fallback system font immediately, then swap to your chosen font when it loads. The second approach is better for users, and most Google Fonts embeds include it by default now.
What are some common fixes?
The fix is serving your fonts from your own domain instead of Google's. This removes the extra round-trip entirely. The OMGF (Optimize My Google Fonts) plugin does this automatically: install it, run the scan, and it downloads and serves your fonts locally with no coding required.
If your theme uses multiple font weights (regular, medium, bold), consider switching to a variable font. Instead of downloading a separate file for each weight, one file contains all of them. Fewer requests, same result.
Summary
Most WordPress performance problems are fixable without touching code. A page cache plugin resolves the TTFB issue for the majority of sites. WP Rocket or LiteSpeed Cache handle render-blocking CSS and deferred JavaScript in a few clicks. OMGF sorts out Google Fonts in minutes.
The hero image (LCP) and JavaScript interaction (INP) problems are more specific to your theme and page builder. The diagnostic steps above will tell you exactly what you're dealing with before you change anything.
If you want to see which of these are affecting your site, scan it with Metrical. It breaks down the real issues in plain language, ranked by impact.