Common Mistakes That Kill Website Performance and How to Fix Them

Website performance is not just a technical nice-to-have. It affects how many people stick around, how confident they feel about contacting you, and how well your pages hold up in search. Most of the slow sites we see are not slow because someone forgot to install a caching plugin. They are slow because of structural choices that add weight everywhere, all the time. In this article we will walk through the common mistakes that quietly kill speed – like one-size-fits-all WordPress templates, page builders such as Elementor, heavy animations, oversized media, too many fonts, and scripts that load on every page for no good reason. The right approach is simple: measure first, remove the waste, then optimise what is left.

How Google Evaluates Websites For Search Rankings Including Structure User Experience Page Speed Content Relevance And Authority Signals

1) Mistake: Choosing an all-purpose WordPress theme (and expecting it to be fast)

Multipurpose themes are built to cover every type of website, so they ship lots of code and features you will never use.

Most off-the-shelf “do everything” themes are slow by design. Not because the developer is careless, but because the theme has to support dozens of layouts, page types, and feature combos out of the box. That flexibility comes with weight.

In practice, these themes often load extra CSS and JavaScript on every page, even when the feature is not used. CSS is the styling code. JavaScript is the code that adds behaviour, like sliders and popups.

You will see things like icon libraries, slider scripts, animation helpers, mega menu code, and integrations for newsletters, shops, forms, and galleries. The theme cannot reliably guess what you will need later, so it loads a lot “just in case”. Template parts follow the same pattern. A wordpress theme built for every scenario includes multiple headers, footers, blog layouts, and page templates, plus the logic to switch between them.

The real problem is that the bloat is not limited to one page. It becomes site-wide overhead. Even a simple Contact page ends up carrying the same baseline weight as your busiest landing page, because the theme loads a global bundle of assets across the whole site.

There are a few common signs this is what you are dealing with:

  • Large amounts of unused CSS and JS in performance reports. You will see warnings like “reduce unused CSS” or “remove unused JavaScript”.
  • Inconsistent results after “optimisation”. You add caching, minification, image compression, and it improves a bit, then hits a wall.
  • Confusing bottlenecks. Sometimes the server response is fine but the page still feels heavy, because the browser is chewing through large files. Other times you might see a slow TTFB and assume hosting is the issue, when the theme is adding work on every request.

TTFB means Time To First Byte. It is how quickly your server starts responding, before the browser even begins rendering the page.

Fixing this usually means making a structural choice, not just tweaking settings.

Option 1: Build a bespoke template around your actual layouts. This is the cleanest route when performance matters. You only code what the site needs: specific page templates, the real header and footer, the components you actually use. Fewer moving parts. Less “just in case” loading.

Option 2: Use a minimal starter theme and keep strict control of what loads. This can work well if you have a clear design system and someone who will enforce it. The key is being disciplined: only enqueue CSS and JS when a page needs it, and avoid bundling features site-wide because they might be useful later.

You can improve a heavy multipurpose theme, and sometimes it is the right call if a rebuild is not realistic. But there is a ceiling. If the theme’s core approach is to load big bundles everywhere, you can trim the edges, but you will not get it to feel like a lean site built for one business.

2) Mistake: Building the site with Elementor (or similar page builders) and then trying to ‘optimise’ afterwards

Page builders make it easy to design, but they add structural weight that is hard to undo later

Elementor and similar builders can produce good looking pages quickly. We have used them. We also see the same pattern when performance matters: you can cache and compress, but you still end up fighting the way the page is built.

Most builders add extra layers between your content and the browser. That usually means nested containers, wrapper divs, and lots of small elements that exist only to control layout. It is not “wrong”, but it creates a bigger DOM.

DOM means the page structure the browser has to build and manage. A larger DOM takes longer to render and is slower to interact with, especially on mid-range phones.

They also tend to add inline styles, often generated per element. That makes the HTML heavier and can reduce how effective browser caching is for styling, because the style is baked into each page instead of living in one reusable stylesheet.

Then there are the assets. Many builders load global CSS and JavaScript across the whole site, plus extra scripts for widgets like sliders, tabs, popups, carousels, counters, and motion effects. Even if you only use a couple of widgets, the base files often load everywhere because the builder cannot reliably predict what each page needs.

This is where Core Web Vitals start to wobble in real use.

LCP (Largest Contentful Paint) is about how quickly the main content appears. Builder pages often delay this because the browser is processing more HTML, more CSS, and more scripts before it can paint the key section of the page.

INP (Interaction to Next Paint) is about how responsive the page feels when someone taps, clicks, or types. Extra scripts and heavy layout work can block the main thread, so simple actions feel laggy, especially when there are animations, sticky headers, popups, or lots of moving parts.

Caching does help. It reduces server work and can make repeat visits quicker. But caching does not remove the structural overhead in the page. The browser still has to download, parse, and execute the same CSS and JavaScript, and it still has to build the same heavy DOM on every visit.

If you want consistently fast results, the fix is usually structural.

Option 1: Use native WordPress blocks (Gutenberg). Blocks are not automatically “fast”, but they are closer to the platform and typically produce cleaner markup with fewer wrappers. You can also keep a tighter grip on what loads site-wide.

Option 2: Use a custom block set. This is the middle ground we often prefer for business sites. You get a controlled library of sections your team can reuse, but each block is built to be lean and only load what it needs.

If a full rebuild is not realistic, do not try to “convert the whole site” in one go. Also, be wary of one-click converter promises. They rarely produce clean code, and they do not solve the underlying layout and asset issues.

A realistic approach is to rebuild the highest-traffic or highest-value pages first. Usually that is the homepage, your main service pages, and your top landing pages from ads or search. Replace those with block-based versions, keep the design consistent, and measure the change before you touch the rest.

Measure with a mix of tools: Google Search Console for Core Web Vitals trends, and Lighthouse or PageSpeed Insights for page-level checks. You are looking for repeatable improvement, not a single perfect score on one test run.

Judgement call: if the site’s main job is lead generation or bookings, and speed matters for SEO and conversions, it is usually worth moving away from a builder over time. If the site changes weekly and speed is “nice to have”, you might accept the trade-off and focus on trimming the worst pages and heaviest widgets.

3) Mistake: Animations and interactions that look good but cost performance

Motion can be done responsibly, but some effects force the browser to do extra work before the page feels ready

A bit of movement can help. It can guide the eye, confirm a click, or make a section feel calmer and clearer. The problem is when the site behaves like a demo reel. Then you pay for it in load time and responsiveness.

The common offenders are usually the same:

  • Scroll-based effects where everything fades, slides, or counts up as you move down the page
  • Large animated hero sections with multiple layers moving at once
  • Parallax backgrounds
  • Multiple simultaneous transitions on hover, scroll, and page load

Why it hurts comes down to how browsers work. They have a “main thread”, which is the bit doing most of the thinking. If it is busy running scripts and recalculating layouts, taps and scrolls feel delayed.

Some animations also trigger repeated layout work. That is when the page keeps re-measuring and re-positioning elements while you scroll. You will not always see it, but you feel it as stutter, delayed input, or a page that loads but does not settle.

Then there is raw load. Heavy motion effects often mean more JavaScript running, more event listeners, and more time spent on the CPU and GPU. On a decent laptop it might look fine. On a mid-range phone, it can tip the whole page over.

Fixing it does not mean removing all motion. It means reducing scope and being picky.

  • Animate fewer elements. Pick one focal point in a section, not six things at once.
  • Reduce how often it runs. Avoid effects that run continuously while scrolling if you can.
  • Prefer CSS transforms and opacity. Moving with transform and fading with opacity is usually cheaper than animating size, position, or shadows.
  • Avoid heavy scroll listeners. If an effect needs JavaScript on every scroll tick, question whether it is worth it.
  • Respect prefers-reduced-motion. This is a user setting that asks sites to minimise motion for comfort and accessibility.

In practice, the fastest “polished” sites tend to use small transitions that support interaction, like a subtle button hover, an accordion opening, or a simple fade-in on one key element. They do less, but they feel more intentional.

Judgement call: keep the fancy stuff only when it supports a clear business goal. If motion helps explain a product, draws attention to a form, or improves understanding, it may be worth the cost. If it is there because it looked good in a template preview, it usually is not.

4) Mistake: Hero banners packed with video, sliders, or oversized imagery

The first thing people see also sets how fast the whole site feels, and it is often the biggest thing the browser has to load.

The hero section at the top of a page does a lot of heavy lifting. It sets the tone, shows your offer, and usually contains the largest visual element on the page. That matters because Google and real users judge speed by what shows up first.

You may hear the term Largest Contentful Paint (LCP). It is simply the moment the main bit of content appears, often the hero image or hero video. If your hero is heavy, your LCP is late. Even if everything else is optimised.

Sliders are a common culprit. They nearly always cost you twice: performance and clarity.

  • Extra images you still pay for – many sliders load multiple slides up front, even though the visitor only sees the first one.
  • Extra scripts and styles – slider libraries add JavaScript, CSS, and logic for swipes, autoplay, pagination, and resizing.
  • Competing messages – three headlines fighting for attention usually converts worse than one clear statement.

In practice, most businesses get better results from one strong hero with one job: explain what you do, who it is for, and what to do next.

Video backgrounds are similar. They can be justified, but only in specific cases. For example, if movement is the product (fitness, events, hospitality) and the clip genuinely helps someone understand the experience quickly. Even then, it needs to be lightweight and handled carefully.

They are usually not justified when the video is decorative, repeats stock footage, or sits behind text that could sit on a normal image. You add load, you add CPU work, and on mobile it can be messy. Some phones restrict autoplay, some save data, and some users just do not want their first interaction with your site to be a moving background.

The fixes are often simple, and they tend to make the site feel more deliberate.

  • Use a single strong image instead of a slider. One message, one visual, one call to action.
  • Use modern formats like WebP or AVIF where appropriate, with a sensible fallback if needed.
  • Serve the correct size – do not send a 3000px wide image to a mobile screen that will display it at a fraction of that.
  • Preload the real hero image if it is your LCP element, so the browser prioritises it early.
  • Lazy-load media below the fold so the browser focuses on what is visible first.

Two quick practical checks we do on almost every build. First, open the page on your phone using mobile data and see what shows up before anything else. If it is a blank block waiting on a hero, you have found the bottleneck. Second, check the image file being served to mobile. If it is huge, you are wasting time and data.

Judgement call: if you need a hero video, treat it like a supporting detail, not the foundation. Make sure the page still looks complete with a static poster image, and only let the video enhance the experience once the essentials are already there.

5) Mistake: Too many fonts, too many weights, and fonts loading from remote services

Typography choices affect load time and visual stability, not just how the site looks

Fonts are easy to overlook because they feel like a design detail. In reality they behave like assets, just like images and scripts. Too many of them will slow down the first view of the page and can make text jump around as it loads.

Every font family and weight you add usually means another file to download. Regular, medium, bold, italic, plus headings in a different family can quickly turn into a long list. Those files are not tiny either, and they often load early because the browser needs them to render text properly.

When the font arrives late, you typically get one of two problems. Either the text stays invisible for a moment, or it shows in a fallback font first and then swaps. That swap is what can cause layout shift. Layout shift is simply content moving after it looked like it had already loaded, which is distracting and can hurt the perceived quality of the site.

Remote font hosting can add extra latency as well. It is not always bad, but it depends on caching, geography, and how quickly the visitor can reach that provider. A visitor in London may get a fast response, while someone elsewhere might have an extra round trip and a slower connection. You also introduce another dependency outside your server, which can be fine, but it is still one more moving part.

Fixing font performance is usually straightforward, and the best gains come from simplifying.

  • Reduce families and weights. As a rule, aim for one family for body text and one for headings, or even one for everything. Keep weights tight. Regular plus bold is often enough for most business sites.
  • Use system fonts where it makes sense. System fonts load instantly because they are already on the device. They are not always right for brand-heavy sites, but they can be a sensible choice for content-first pages, blogs, or resource sections.
  • Self-host fonts when it is the better fit. Hosting the files on your own domain can reduce external dependencies and give you more control over caching. It is not mandatory, and it is not magic, but it can be a solid improvement when remote fonts are causing delays.
  • Subset the character set. Many font files include huge language ranges you do not need. Subsetting means keeping only the characters you actually use, which cuts file size. If you need multiple languages, do it deliberately rather than shipping everything by default.
  • Set font-display properly. This controls how the browser behaves while the font loads. In plain terms, it helps avoid invisible text and reduces the “blank page” feeling at the top of a load.

There is a real trade-off here. Brand typography matters, especially if you are in a design-led space or you want a distinctive feel. But most businesses do not need five weights and two decorative families to look professional. A good middle ground is one high-quality brand font for headings, paired with a reliable, readable option for body text, then keep the weights to the minimum that supports the hierarchy.

Small judgement call: if performance is already under pressure from heavy imagery, video, or complex pages, fonts are one of the easiest places to simplify without changing your message. People notice speed and stability more than they notice whether your body text is set in a slightly more unique typeface.

6) Mistake: ‘Just one more script’ – third-party tags and plugins that load on every page

Small add-ons add up fast, so only load code where it actually earns its place

This is one of the most common performance killers we see on business sites. It rarely starts as a big decision. It is usually a handful of “quick wins” added over time, then the site begins to feel heavy.

Common sources are chat widgets, tracking stacks (analytics plus ads plus heatmaps), popups and lead capture tools, review widgets, embedded maps, and social feeds. Each one brings its own JavaScript, styles, fonts, and network calls. Even if it looks small on the page, it can be doing a lot behind the scenes.

Why it hurts comes down to a few predictable things:

  • Extra network requests. The browser has to fetch more files from more places, often before the page can fully settle.
  • Render-blocking resources. Some files must be downloaded and processed before the page can paint properly. Render-blocking means “it delays what the visitor sees”.
  • Long tasks. JavaScript can keep the browser busy for chunks of time, which makes scrolling, tapping, and typing feel laggy.
  • Privacy and consent complexities. More third-party tags usually means more cookies and more consent rules to handle properly, which can also delay when scripts are allowed to run.

The awkward part is that these issues do not always show up in a basic speed score. A page can “load” quickly but still feel sluggish because scripts keep working after the first view appears.

Fixing it is mostly about being deliberate.

  • Audit what is loading. Make a list of every script, tag, and embed. You are looking for things nobody uses, experiments that never got removed, and “we already have this” duplicates.
  • Remove overlaps. Two tools that both add popups, or two plugins that both add tracking events, is a quiet way to double your load.
  • Defer or async where appropriate. This tells the browser not to block the page while downloading non-essential scripts. It is not safe for everything, so it needs testing.
  • Load conditionally by page or template. If the map is only on the contact page, it should not load on blog posts. Same for review widgets that only appear on one landing page.
  • Replace heavy embeds with lightweight placeholders. Use a static image preview for maps or social feeds, then load the real embed only when someone clicks. This usually improves both speed and consent handling.

WordPress adds its own trap here: plugin sprawl. It is easy to end up with ten plugins that each add a small feature, and half of them load assets site-wide. It is also common to have overlapping features, like a page builder plus a popup plugin plus a form plugin plus a marketing plugin, all competing to do similar work.

A good rule is fewer, better plugins. If a plugin is business-critical, keep it and make it behave. If it is “nice to have”, be honest about whether it is worth slowing down every page for every visitor.

Small judgement call: if you are serious about performance, be especially cautious with anything that injects code on every page. A chat widget, a social feed, or a fancy popup might help conversions on one page, but it rarely deserves to tax your whole site.

7) Mistake: Global code and assets that should be page-specific

Split your site into page types, then only load what each type actually uses

A lot of slow sites are not slow because any one feature is “too big”. They are slow because the same pile of code gets loaded everywhere, even when it is only needed on one page.

This is what we mean by global assets. CSS and JavaScript files that are enqueued site-wide, so every visitor downloads them on every page. Even if the feature is not visible.

Common examples we see in WordPress:

  • Contact form assets loading on every page, even though the form only exists on the contact page.
  • A slider library loaded site-wide because there is one hero slider on the homepage.
  • Ecommerce scripts running on blog posts and service pages, even when the shop is a small part of the site.

The symptom is usually the same. Pages that should be light still feel heavy, because the browser is downloading and parsing code it cannot use. Parsing just means “reading and preparing code so it can run”. That work takes time.

The structural fix is to think in templates, not individual pages. Homepage. Service page. Blog post. Contact. Case study. Shop. Then load assets per template, not for the whole site.

In WordPress, there are a few practical ways to do this without turning your site into a science project:

  • Conditional enqueuing – only load a script or stylesheet when certain conditions are true (for example, only on the contact page, or only on product pages).
  • Template-specific bundles – one small set of files for each page type, instead of one giant “everything” file for the entire site.
  • Custom blocks with minimal CSS/JS – if you use a bespoke block for something interactive, ship only what that block needs, and only when the block is actually on the page.

This is much easier when the site is built on a bespoke template, because you control what the template outputs and what it needs. You can keep the base lean, then add features in a targeted way.

It is harder with multipurpose themes and page builders. They are designed to cover every possible layout and feature, so they tend to load broader libraries “just in case”. You can sometimes tame it, but there is a point where you are fighting the architecture.

Small judgement call: if performance matters and your site is not a one-page brochure, avoid setups where you cannot control asset loading per template. It is not about being fancy. It is about being predictable.

How do you validate the improvement? Do not rely on a single score. Look at what changed.

  • Coverage in your browser dev tools – it shows how much CSS/JS is actually used on a page versus what was downloaded.
  • Network waterfalls – the timeline view of requests, showing what loads, when it loads, and what blocks other work.

Run a before and after on a “simple” page like a blog post. If you split assets properly, you should see fewer files, less unused code, and a calmer waterfall. That usually translates to a site that feels quicker, not just one that looks good on a report.

8) Mistake: Treating performance as a plugin, not a build discipline

Speed is mostly decided before you install any optimisation tool, because it comes from what you build, what you load, and what you choose to avoid.

A lot of WordPress performance work gets approached backwards. Someone installs a caching plugin, adds “optimise CSS”, switches on everything, and hopes the site will feel fast. Sometimes you get a small win. Often you just hide the real problem, which is too much stuff being shipped to every page.

Plugins and CDNs help, but only after you remove waste. If the base theme, template, or builder is structurally heavy, you are trying to compress a problem that should have been avoided in the first place.

Here is the sensible order of operations we use on client sites:

  1. Measure what users actually experience and what the lab reports say.
  2. Remove bloat – features, layouts, and global assets that do not need to be there.
  3. Optimise media – right sizes, modern formats, and no unnecessary video weight.
  4. Control fonts – fewer families and weights, and avoid slow remote loading where possible.
  5. Control scripts – load only what each page type needs, and delay or remove the rest.
  6. Then cache – page caching, object caching, and delivery improvements once the site is lean.

What to measure, at a high level: focus on real user experience, not just a single score. Lab tests are the controlled tests you run in tools. Real user data is how the site behaves for actual visitors on real devices and networks.

If you want three metrics to keep in mind, use the Core Web Vitals:

  • LCP (Largest Contentful Paint) – how long it takes until the main content looks “loaded”.
  • INP (Interaction to Next Paint) – how quickly the site responds when someone clicks or taps.
  • CLS (Cumulative Layout Shift) – how much the layout jumps around while loading.

You do not need to become a performance engineer to use these. Just treat them as a way to describe the experience: does it show up quickly, does it respond quickly, does it stay stable.

When should you get help? Two common cases. First, when the site is structurally heavy, like a multipurpose theme, a template that ships every feature under the sun, or a page builder setup where you cannot control what loads. Second, when revenue depends on speed – if leads, bookings, or sales drop when the site feels slow, it is worth fixing properly rather than patching it.

A simple rule we use on builds: if you cannot stop it loading, you do not control it. That applies to theme frameworks, builder widgets, animation libraries, and third-party embeds. If you cannot selectively load it per page, you are stuck paying for it everywhere.

Small judgement call: if performance matters to your business, pick a setup where you can predict what loads on each template. Native blocks with a bespoke template are usually easier to keep lean than a one-size-fits-all theme plus a page builder. You will spend less time firefighting, and more time improving what the site actually does.

FAQ

Caching helps deliver pages faster once the browser already has something usable to load, but it does not remove the weight you are shipping to every visitor. If your theme, template, or page builder loads big CSS and JavaScript on every page, caching will still serve that same bundle, just from a quicker place. The same goes for oversized images, background videos, lots of fonts, and third-party scripts.

When a WordPress site stays slow after caching, it is usually because the front end is heavy or uncontrolled. Multipurpose templates and builders like Elementor are common culprits because they load assets for many scenarios you are not using. The fix is to reduce what each page needs to load: leaner bespoke templates, native blocks where possible, properly sized media, fewer fonts, and scripts that only load on the pages that actually use them.

You can optimise an Elementor site, and sometimes it ends up “good enough” for a brochure site. You can tighten images, cut back widgets, disable unused features, reduce third party scripts, and cache properly. But there is usually a performance ceiling because Elementor adds extra markup, CSS, and JavaScript that you cannot fully remove or load selectively per template.

A rebuild is worth considering when speed is tied to leads or sales, when Core Web Vitals stay stubborn after sensible optimisation, or when every page ships the same heavy assets even though only one page needs them. In those cases, moving to native blocks with a bespoke template often gives you better control over what loads, and that is what tends to make the site consistently fast.

The biggest win is removing structural bloat so every page ships less code by default. In practice that usually means ditching a heavy multipurpose template or Elementor setup for a lean, bespoke WordPress template using native blocks, then simplifying the hero area (no giant videos or complex animations unless they earn their keep) and stopping scripts from loading site-wide when they are only needed on one page.

Measure before and after so you know what actually improved. Check Core Web Vitals and a simple page weight view, then change one thing at a time and retest. If you cannot stop an asset loading, you do not control it, and it will keep costing you performance on every visit.

In most cases, self-hosting fonts is the safer performance choice because you control caching, preload behaviour, and you avoid an extra third-party request that can add latency on slower connections. It can also simplify privacy and compliance, since the browser is not calling Google’s servers just to fetch typography. Google Fonts can still work fine, and some visitors may already have them cached, but you are giving up control and relying on another domain behaving well.

Our rule of thumb: if speed and control matter, self-host and keep it simple. Whichever route you take, the biggest win is usually not where the fonts live, it is how many you load. Stick to one family where possible, cut weights hard (often 2 is enough), avoid loading italics unless you use them, and make sure you are not pulling fonts site-wide for one small design flourish.

Open the page in Chrome, right click and choose Inspect, then go to the Network tab, tick Disable cache, and reload. Sort by JS and look for big files, lots of requests, and scripts coming from third party domains. Then check the Performance tab and record a load. Look for long tasks on the main thread and click into them to see which script file is responsible. If you see the same script showing up across pages where it does nothing, that is usually the real drag.

Next, make a simple list of what loads on every key page type – home, service page, blog post, contact, checkout if you have one. Compare the script list between pages. In WordPress, a script manager style plugin can help you spot which plugin enqueues which file, but treat it as a map, not a fix. Your goal is to remove or conditionally load scripts so only the pages that need them pay the cost.

No. Small, purposeful animation can be fine, especially if it runs after the main content has loaded and does not cause layout shift. The trouble starts when motion is heavy or constant – big sliders, background videos, scroll effects, parallax stacks, and animated page builders often add extra scripts, extra paint work, and more chances to fail LCP, INP, or CLS.

Use motion sparingly, and only where it helps clarity. Keep it CSS-first where possible, avoid animating layout properties, and do not ship animation libraries site-wide if only one page needs them. Also respect reduced motion settings so people who prefer less movement, or are on weaker devices, are not forced to pay the cost.

Words from the experts

We often see the same pattern: a WordPress template or Elementor build that looked fine at first, then slowly picks up extra features, extra scripts, and extra baggage until performance collapses. We often see it because those setups are built for every possible scenario, not your scenario. One practical habit that helps is to list what loads on your key page types and compare them, because it quickly shows you what is being shipped site-wide for no good reason.

Our calm judgement call is this: if performance matters, avoid generic templates and heavy builders and lean into a bespoke Gutenberg build where you control what loads and when. It is not about being fancy, it is about staying disciplined so you are not fighting a system that was never designed to be lean.