Performance Optimisation: Where to Start When Everything Feels Slow
“Our website is slow. Can you make it faster?”
This is one of the most common requests I get. And the answer is always: probably, but first we need to figure out what’s actually slow and why.
Performance optimisation can feel overwhelming. There are dozens of metrics, hundreds of potential issues, and no shortage of advice telling you to optimise everything. But you don’t need to fix everything. You need to fix the right things.
Here’s the systematic approach I use to find and fix performance issues without wasting time on optimisations that don’t matter.
Step 1: Measure What’s Actually Slow
Before you fix anything, you need to know what’s broken.
Tools I use:
Google PageSpeed Insights - Quick overview, shows both lab and field data WebPageTest - Detailed waterfall, shows exactly what’s loading when Chrome DevTools - Performance tab shows real browser behavior Lighthouse - Built into Chrome, good for quick audits
Run tests from:
- Different locations (your users might not be in your country)
- Different devices (mobile vs desktop)
- Different connection speeds (throttle to 3G to see what mobile users experience)
What to look for:
Lab data - Simulated tests in controlled conditions. Good for debugging. Field data (CrUX) - Real user data from Chrome. This is what actually matters.
If your lab scores are bad but field data is good, you might not have a problem. If field data is bad, you definitely have a problem.
Step 2: Identify the Biggest Bottlenecks
Don’t try to fix everything at once. Find the biggest issues first.
Common culprits (in order of frequency):
- Images (80% of the time, this is the problem)
- Third-party scripts (analytics, ads, chat widgets)
- Render-blocking resources (CSS/JS that stops the page from showing)
- Server response time (slow backend or database)
- Unoptimised JavaScript (too much code running on load)
- Missing caching (loading the same things over and over)
Use WebPageTest to see the waterfall. This shows you what’s loading, how large it is, and how long it takes.
Look for:
- Large files (anything over 1MB is suspicious)
- Long requests (anything taking >1 second)
- Third-party domains loading lots of content
- Requests after requests (poor parallelization)
Step 3: The Quick Wins (Do These First)
These fixes take minimal time and usually have the biggest impact:
Images (The #1 Issue)
Problem: Unoptimised images are almost always the biggest performance killer.
Fixes:
- Compress images (use tools like ImageOptim, Squoosh, or your CMS’s compression)
- Use modern formats (WebP or AVIF instead of JPG/PNG)
- Properly size images (don’t load a 3000px image and display it at 300px)
- Lazy load images below the fold
- Add width and height attributes (prevents layout shift)
Quick test: Download your homepage. How much of the total page weight is images? If it’s more than 50%, you have an image problem.
Third-Party Scripts
Problem: Analytics, chat widgets, and ad scripts add hundreds of KB and block rendering.
Fixes:
- Audit what you’re loading (do you need all of it?)
- Remove unused scripts
- Delay non-critical scripts (load after page interactive)
- Use async or defer attributes
Quick test: Disable JavaScript and reload. How fast is it now? That’s how much your scripts are costing you.
Caching
Problem: Serving the same content over and over without caching it.
Fixes:
- Enable browser caching (set cache headers for static assets)
- Use a CDN for static assets
- Enable server-side caching if using a CMS
Quick test: Reload the page a second time. Is it much faster? If not, caching isn’t working.
Render-Blocking Resources
Problem: CSS and JavaScript that must be downloaded before the page can show anything.
Fixes:
- Inline critical CSS
- Defer non-critical CSS
- Move JavaScript to the end of the body or use defer/async
- Reduce the size of critical resources
Quick test: Look at your waterfall. Are CSS and JS files near the top blocking everything else?
Step 4: The Medium Effort Fixes
Once you’ve handled the quick wins:
Optimize Font Loading
Problem: Web fonts block text rendering, causing Flash of Invisible Text (FOIT).
Fixes:
- Use
font-display: swapto show fallback text immediately - Subset fonts (only include characters you need)
- Preload critical fonts
- Consider using system fonts (zero load time)
Code Splitting
Problem: Sending all JavaScript to all users, even if they don’t need it.
Fixes:
- Split code by route (only load what’s needed per page)
- Lazy load components below the fold
- Use dynamic imports for heavy libraries
Database Optimisation
Problem: Slow database queries causing slow page loads.
Fixes:
- Add database indexes
- Optimise slow queries
- Enable query caching
- Use object caching (Redis, Memcached)
Reduce Server Response Time (TTFB)
Problem: Server takes too long to start sending content.
Fixes:
- Enable server-side caching
- Optimise backend code
- Upgrade hosting if necessary
- Use a CDN to reduce distance to users
Step 5: The Advanced Optimisations
Only do these if you’ve exhausted the basics:
Implement Critical CSS
What: Inline the minimum CSS needed to render above-the-fold content. Load the rest later.
Why: Faster first paint, but harder to maintain.
Optimise JavaScript Execution
What: Reduce main thread blocking by splitting up long tasks, using web workers, or deferring non-critical work.
Why: Better interactivity, but requires deeper code changes.
Implement Service Workers
What: Cache assets and pages for offline use and faster repeat visits.
Why: Great for returning users, but adds complexity.
Use Resource Hints
What: Use preconnect, prefetch, preload to tell the browser what’s coming.
Why: Can improve perceived performance, but easy to misuse.
The Performance Budget Approach
Instead of chasing perfect scores, set budgets:
Example budget:
- Total page weight: <2MB
- JavaScript: <300KB
- Images: <1MB
- Time to Interactive: <3 seconds on 3G
- Largest Contentful Paint: <2.5 seconds
Build these into your process. Fail builds that exceed budgets.
This prevents performance degradation over time.
What to Ignore (Yes, Really)
Perfect Lighthouse scores - A 95 that loads in 2 seconds is better than a 100 that takes 3 seconds.
Every single recommendation - Not all optimisations provide equal value. Focus on user-facing metrics.
Micro-optimisations before macro ones - Don’t spend hours shaving 10ms off JavaScript when you have 2MB of unoptimised images.
Comparing lab scores - Field data (real users) matters more than simulated tests.
How to Maintain Performance
Performance degrades over time if you don’t protect it:
Set up monitoring:
- Use a tool like SpeedCurve, Calibre, or Lighthouse CI
- Track performance on every deploy
- Alert when metrics regress
Make it part of the process:
- Review performance in code reviews
- Test on real devices, not just dev machines
- Include performance in your definition of done
Regular audits:
- Quarterly check-up on scripts and assets
- Remove unused dependencies
- Compress new images
The Reality Check
Sometimes the answer is “your site is fundamentally too complex for good performance on the current architecture.”
If you’re running a giant e-commerce platform on shared hosting with 50 plugins, no amount of image optimisation will make it fast. You might need:
- Better hosting
- Architectural changes
- Fewer dependencies
- A simpler tech stack
Sometimes the fix isn’t optimisation—it’s rebuilding smarter.
My Step-by-Step Process (Summary)
- Measure - Run PageSpeed Insights and WebPageTest
- Identify - Find the top 3 bottlenecks
- Quick wins - Fix images, remove unused scripts, enable caching
- Medium effort - Optimise fonts, code splitting, database tuning
- Measure again - Did it work?
- Set up monitoring - Prevent regression
Don’t optimise everything. Optimise what matters.
The Most Important Question
Before you start optimising, ask: How slow is too slow, and for whom?
If your site loads in 3 seconds on desktop and your users are all on desktops with good connections, you might not have a problem worth solving.
If your site loads in 8 seconds on mobile and 70% of your users are on mobile, you have a serious problem.
Context matters. Real user data matters. Lighthouse scores don’t pay the bills—happy users do.
The Bottom Line
Performance optimisation isn’t about achieving perfect scores. It’s about removing friction for users.
Start with measuring. Identify the biggest bottlenecks. Fix those first. Measure again.
Most sites can get 80% of the benefit from 20% of the work: optimise images, remove unused scripts, enable caching.
If you’re still slow after that, dig deeper. But don’t skip the basics to chase advanced optimisations.
What performance issues have you encountered? What fixes gave you the biggest wins?