opdeck / blog / improve-google-pagespeed-insights-score

How to Improve Your Google PageSpeed Insights Score with OpDeck

April 21, 2026 / OpDeck Team
PageSpeedSEOOptimizationWeb PerformanceGoogle Insights

If you're trying to improve your Google PageSpeed Insights score, you've come to the right place. A low PageSpeed score doesn't just hurt your pride — it directly impacts your search rankings, bounce rates, and ultimately your revenue. In this guide, we'll walk through every major optimization technique you can implement today, explain why each one matters, and show you how to use OpDeck's Website Performance Analyzer to identify exactly what's dragging your score down before you write a single line of code.


What Google PageSpeed Insights Actually Measures

Before diving into fixes, it's worth understanding what the tool is actually scoring. Google PageSpeed Insights (PSI) runs a Lighthouse audit against your URL and grades your page across four categories: Performance, Accessibility, Best Practices, and SEO. When most people talk about their "PageSpeed score," they mean the Performance score, which is a weighted composite of six Core Web Vitals and lab metrics:

  • First Contentful Paint (FCP) — How quickly the first piece of content appears
  • Largest Contentful Paint (LCP) — How long until the largest visible element loads
  • Total Blocking Time (TBT) — How much time JavaScript blocks the main thread
  • Cumulative Layout Shift (CLS) — How much the page layout shifts unexpectedly
  • Speed Index — How quickly content is visually populated
  • Interaction to Next Paint (INP) — How responsive the page is to user interactions

LCP and TBT carry the most weight in the overall score (roughly 25% each), so fixing those two metrics alone can dramatically move your number. The score itself ranges from 0–100, with 90+ considered "Good," 50–89 "Needs Improvement," and below 50 "Poor."


How to Run a Baseline Audit Before Making Changes

You can't fix what you haven't measured. Start by running a full audit with OpDeck's Website Performance Analyzer. It performs a Lighthouse-based audit and surfaces the exact issues PSI would flag, along with prioritized recommendations. This gives you a clear before/after baseline so you can confirm whether your changes are actually working.

Here's a simple workflow:

  1. Go to OpDeck Website Performance and enter your URL
  2. Run the audit and note your current Performance score
  3. Screenshot or export the diagnostics panel
  4. Make one category of changes at a time
  5. Re-run the audit to measure the delta

Changing everything at once makes it impossible to know which fix actually helped. Work systematically.


How to Improve Your Google PageSpeed Insights Score: The Core Fixes

1. Optimize and Compress Images

Images are almost always the single largest contributor to page weight and slow LCP times. A 4MB hero image that could be 200KB is a five-second penalty hiding in plain sight.

What to do:

  • Convert to modern formats. Use WebP or AVIF instead of JPEG or PNG. WebP files are typically 25–35% smaller than JPEG at equivalent quality.
  • Compress aggressively. Tools like Squoosh, ImageOptim, or Sharp (for Node.js pipelines) can reduce file sizes by 60–80% without visible quality loss.
  • Serve correctly sized images. Don't serve a 1200px image to a 400px mobile viewport. Use the srcset attribute to serve appropriately sized images per device.
  • Add explicit width and height attributes. This prevents layout shifts (CLS) because the browser knows how much space to reserve before the image loads.
<img
  src="hero.webp"
  srcset="hero-400.webp 400w, hero-800.webp 800w, hero-1200.webp 1200w"
  sizes="(max-width: 600px) 400px, (max-width: 1000px) 800px, 1200px"
  width="1200"
  height="630"
  alt="Hero image description"
  loading="lazy"
/>

The loading="lazy" attribute defers off-screen images, which directly improves FCP and LCP by letting the browser prioritize above-the-fold content.


2. Eliminate Render-Blocking Resources

Render-blocking resources are CSS and JavaScript files that force the browser to pause HTML parsing until they finish downloading and executing. This is one of the most common reasons for poor FCP and TBT scores.

For JavaScript:

Add defer or async to non-critical scripts. The defer attribute tells the browser to download the script in the background and execute it after the HTML is parsed.

<!-- Instead of this -->
<script src="analytics.js"></script>

<!-- Do this -->
<script src="analytics.js" defer></script>

Use async for scripts that don't depend on other scripts (like standalone analytics snippets). Use defer for scripts that need to run in order.

For CSS:

Critical CSS (the styles needed to render above-the-fold content) should be inlined in the <head>. Non-critical CSS should be loaded asynchronously:

<link rel="preload" href="styles.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
<noscript><link rel="stylesheet" href="styles.css"></noscript>

Tools like Critical (npm package) can automatically extract and inline your critical CSS.


3. Implement Effective Caching

Browser caching lets repeat visitors load your page almost instantly because their browser already has your assets stored locally. Without proper cache headers, every visit re-downloads everything.

Set long cache durations for static assets (images, fonts, CSS, JS) and shorter durations for HTML:

# Nginx configuration
location ~* \.(jpg|jpeg|png|gif|webp|svg|ico|css|js|woff2)$ {
    expires 1y;
    add_header Cache-Control "public, immutable";
}

location ~* \.html$ {
    expires 1h;
    add_header Cache-Control "public, must-revalidate";
}

For Apache, add this to your .htaccess:

<IfModule mod_expires.c>
    ExpiresActive On
    ExpiresByType image/webp "access plus 1 year"
    ExpiresByType text/css "access plus 1 year"
    ExpiresByType application/javascript "access plus 1 year"
    ExpiresByType text/html "access plus 1 hour"
</IfModule>

The key principle: use content-hashed filenames for CSS and JS (e.g., main.a3f9c2.js) so you can safely set 1-year cache durations. When the file changes, the filename changes, busting the cache automatically.


4. Reduce JavaScript Execution Time

Total Blocking Time (TBT) is almost entirely driven by JavaScript. Long tasks — JS that runs for more than 50ms on the main thread — block user interactions and tank your score.

Audit your JS bundle:

Use tools like Webpack Bundle Analyzer or Vite's built-in rollup visualizer to see what's inside your bundle. You'll often find:

  • Entire libraries imported when you only use one function (e.g., importing all of Lodash for _.debounce)
  • Polyfills for browsers you don't support
  • Duplicate dependencies

Tree-shake and code-split:

// Instead of importing the whole library
import _ from 'lodash';

// Import only what you need
import debounce from 'lodash/debounce';

Code splitting with dynamic imports:

// Load heavy components only when needed
const HeavyChart = React.lazy(() => import('./HeavyChart'));

// Or with vanilla JS
button.addEventListener('click', async () => {
    const { initModal } = await import('./modal.js');
    initModal();
});

Remove unused JavaScript:

Run a Coverage audit in Chrome DevTools (F12 → More Tools → Coverage) to see what percentage of your JS is actually executed on page load. Anything above 50% unused is a red flag.


5. Enable Text Compression (Gzip or Brotli)

Text-based assets (HTML, CSS, JS) compress extremely well. Brotli typically achieves 15–20% better compression than Gzip. Most modern servers and CDNs support both.

Nginx:

# Enable Brotli (requires ngx_brotli module)
brotli on;
brotli_comp_level 6;
brotli_types text/html text/css application/javascript application/json;

# Fallback Gzip
gzip on;
gzip_types text/html text/css application/javascript application/json;
gzip_comp_level 6;

Verify compression is working:

curl -H "Accept-Encoding: br" -I https://yoursite.com/main.js
# Look for: Content-Encoding: br

If you're on a CDN like Cloudflare, compression is typically enabled by default. Check your dashboard to confirm.


6. Optimize Web Fonts

Web fonts are a silent performance killer. Loading four font weights from Google Fonts can add 300–500ms to your FCP.

Best practices:

  • Use font-display: swap to prevent invisible text during font loading
  • Preconnect to font origins to reduce DNS lookup time
  • Self-host fonts when possible (eliminates third-party DNS lookup entirely)
  • Subset fonts to include only the characters you actually use
<!-- Preconnect to Google Fonts -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>

<!-- Load with font-display: swap -->
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600&display=swap" rel="stylesheet">

For self-hosted fonts:

@font-face {
    font-family: 'Inter';
    src: url('/fonts/inter-400.woff2') format('woff2');
    font-weight: 400;
    font-style: normal;
    font-display: swap;
}

WOFF2 is the most compressed font format — always use it as your primary format.


7. Minimize and Defer Third-Party Scripts

Third-party scripts (chat widgets, marketing pixels, A/B testing tools, social embeds) are often the biggest performance offenders because you have no control over their servers. A single slow third-party script can add 1–2 seconds to your TBT.

Audit your third parties:

In Chrome DevTools, go to the Network tab, filter by domain, and sort by size and time. Identify which third-party domains are the slowest.

Defer non-critical third parties:

// Load chat widget only after user interaction
let chatLoaded = false;

function loadChat() {
    if (chatLoaded) return;
    chatLoaded = true;
    // Load your chat script here
    const script = document.createElement('script');
    script.src = 'https://chat-provider.com/widget.js';
    document.head.appendChild(script);
}

// Load on first user interaction
document.addEventListener('mousemove', loadChat, { once: true });
document.addEventListener('touchstart', loadChat, { once: true });

This technique — called "facade" or "lazy loading on interaction" — is recommended by Google's web.dev guidelines and can dramatically reduce TBT on initial page load.


8. Use a Content Delivery Network (CDN)

A CDN distributes your static assets across servers worldwide, so a user in Tokyo gets your CSS from a Tokyo server rather than your origin server in Virginia. This reduces Time to First Byte (TTFB) significantly.

For most sites, the easiest CDN implementation is Cloudflare's free tier, which also handles compression, caching, and DDoS protection automatically.

Preconnect to CDN origins:

<link rel="preconnect" href="https://cdn.yoursite.com">
<link rel="dns-prefetch" href="https://cdn.yoursite.com">

9. Fix Cumulative Layout Shift (CLS)

CLS measures visual instability — elements jumping around as the page loads. Common culprits include:

  • Images without explicit dimensions
  • Ads and embeds without reserved space
  • Dynamically injected content above existing content
  • Web fonts causing text reflow

Reserve space for ads and embeds:

.ad-container {
    min-height: 250px; /* Reserve space before ad loads */
    width: 300px;
}

Avoid inserting content above the fold dynamically. If you must show a banner or notification, always reserve the space in your initial layout or append it at the bottom.


10. Optimize Your Server Response Time (TTFB)

Even perfect front-end optimization can't compensate for a slow server. If your Time to First Byte is above 600ms, investigate:

  • Database query optimization — Use query caching, add indexes, optimize slow queries
  • Server-side caching — Cache rendered HTML with tools like Redis, Varnish, or full-page caching plugins (for WordPress: WP Rocket, W3 Total Cache)
  • Upgrade your hosting — Shared hosting often has poor TTFB; consider a VPS or managed hosting

For WordPress sites specifically, enabling object caching and a full-page cache plugin is usually the single highest-impact change you can make.


How to Prioritize What to Fix First

Not all fixes are equal. Here's a rough priority order based on typical impact:

Priority Fix Typical Score Impact
1 Optimize images (compress + WebP) High
2 Defer/remove unused JavaScript High
3 Enable caching Medium-High
4 Eliminate render-blocking resources Medium-High
5 Enable text compression Medium
6 Fix CLS issues Medium
7 Optimize web fonts Medium
8 Defer third-party scripts Medium
9 Use a CDN Medium
10 Improve TTFB Variable

Start with images and JavaScript — they're responsible for the majority of performance problems on most websites.


Tracking Progress: Measure After Every Change

After implementing each fix, re-run your audit with OpDeck's Website Performance Analyzer to confirm the improvement. Keep a simple log:

Date       | Change Made              | Score Before | Score After
-----------|--------------------------|--------------|------------
2024-01-15 | Converted images to WebP | 52           | 67
2024-01-16 | Deferred analytics JS    | 67           | 74
2024-01-17 | Inlined critical CSS     | 74           | 81

This approach keeps you accountable and helps you identify which changes have the most impact on your specific site.


Common Mistakes That Prevent Score Improvements

  • Testing the wrong URL. Always test the specific page you optimized, not just the homepage.
  • Testing on a staging server. CDN and caching behavior differs from production. Test both.
  • Ignoring mobile scores. PSI scores mobile and desktop separately. Mobile scores are typically 20–30 points lower. Google uses mobile-first indexing, so mobile performance matters more for SEO.
  • Over-optimizing for the score rather than real users. Field data (from real users via Chrome UX Report) matters as much as lab data. A 90 lab score with poor field data won't help your rankings.
  • Forgetting to re-test after adding new features. Performance is not a one-time fix — it degrades as you add new content, plugins, and scripts.

Conclusion

Improving your Google PageSpeed Insights score is a systematic process, not a single magic fix. Start by auditing your current baseline with OpDeck's Website Performance Analyzer, then work through the priority list: compress images, reduce JavaScript, implement caching, and eliminate render-blocking resources. Each change compounds on the others, and most sites can reach a 90+ score with consistent effort over a few focused sessions.

The best part? These optimizations don't just improve your score — they make your site genuinely faster for real users, which means lower bounce rates, higher conversions, and better search rankings. Head over to OpDeck right now, run your first audit, and start with whatever the tool flags as your highest-impact issue. You'll likely see a meaningful improvement within an hour.