Core Web Vitals for SaaS: Why Your Website Is Losing Rankings to Faster Competitors
We've audited over 70 funded SaaS websites. The pattern is consistent: most have terrible page speed. Heavy JavaScript bundles, unoptimized images, layout shifts everywhere. Google measures all of this — and it's costing you rankings and conversions.
What Are Core Web Vitals?
Core Web Vitals are three specific metrics Google uses as ranking signals. They measure real user experience — not just server response time. Since 2021, they've been part of Google's page experience signals, and with every algorithm update, their weight has increased.
| Metric | What It Measures | Good | Needs Work | Poor |
|---|---|---|---|---|
| LCP (Largest Contentful Paint) | How fast the main content loads | ≤ 2.5s | 2.5–4s | > 4s |
| INP (Interaction to Next Paint) | How fast the page responds to clicks/taps | ≤ 200ms | 200–500ms | > 500ms |
| CLS (Cumulative Layout Shift) | How much the page layout jumps around | ≤ 0.1 | 0.1–0.25 | > 0.25 |
The 7 Most Common Speed Killers on SaaS Websites
After auditing dozens of SaaS sites — from seed-stage to Series C — these are the issues we find most frequently. They're ordered by impact.
Unoptimized Hero Images and Videos
The biggest LCP killer. SaaS sites love large hero images and product screenshots. But a 2MB PNG hero image means visitors wait 3-5 seconds just for the above-the-fold content.
What we find: Hero images in PNG format (should be WebP/AVIF), no explicit width/height attributes (causes CLS), no lazy loading on below-fold images, and autoplaying background videos that download 10-50MB on page load.
- Convert all images to WebP or AVIF format (60-80% smaller than PNG)
- Add
widthandheightattributes to every<img>tag - Use
loading="lazy"on all images below the fold - For hero images, use
fetchpriority="high"and preload with<link rel="preload"> - Replace background videos with animated WebP or a static image + play button
<!-- Before: 2MB PNG, no dimensions, blocks LCP -->
<img src="/hero-dashboard.png" alt="Dashboard">
<!-- After: 200KB WebP, dimensions set, prioritized -->
<img src="/hero-dashboard.webp" alt="Dashboard"
width="1200" height="675"
fetchpriority="high">
Render-Blocking JavaScript Bundles
SaaS marketing sites built with React, Next.js, or Vue often ship massive JavaScript bundles. The browser can't paint anything until it downloads and parses these scripts. We regularly see 500KB-2MB of JavaScript on a marketing homepage that's essentially a brochure.
What we find: No code splitting (entire app ships on homepage), analytics/chat/tracking scripts in the <head> without async/defer, unused JavaScript from npm packages, and client-side rendering of static content.
- Add
asyncordeferto all third-party scripts (analytics, chat widgets, tracking pixels) - Implement code splitting — only load JS needed for the current page
- Audit your bundle with
npx webpack-bundle-analyzeror Next.js's built-in analyzer - Move to SSG (Static Site Generation) for marketing pages — no JS needed to render content
- Lazy-load chat widgets, video embeds, and interactive demos
<!-- Before: Blocks rendering -->
<script src="https://analytics.example.com/tracker.js"></script>
<script src="https://chat.example.com/widget.js"></script>
<!-- After: Non-blocking -->
<script async src="https://analytics.example.com/tracker.js"></script>
<script defer src="https://chat.example.com/widget.js"></script>
Web Font Loading Causing Layout Shifts
Almost every SaaS site uses custom fonts (Inter, Poppins, DM Sans). When these load late, text reflows and the entire layout shifts — killing your CLS score. We see CLS scores of 0.3-0.5 on sites that look perfectly stable visually — because the shift happens in the first 500ms.
- Use
font-display: swapin your @font-face declarations - Preload your primary font:
<link rel="preload" href="/fonts/inter.woff2" as="font" type="font/woff2" crossorigin> - Self-host fonts instead of loading from Google Fonts (eliminates DNS lookup + connection time)
- Use
size-adjustCSS property to match fallback font metrics to your custom font
/* Prevent layout shift from font loading */
@font-face {
font-family: 'Inter';
src: url('/fonts/inter-var.woff2') format('woff2');
font-display: swap;
size-adjust: 100%;
ascent-override: 90%;
descent-override: 22%;
line-gap-override: 0%;
}
Third-Party Script Overload
SaaS sites stack third-party scripts: Google Analytics, Hotjar, Intercom, HubSpot, Segment, Sentry, Amplitude, LinkedIn Insight, Facebook Pixel, Google Ads. Each one adds 50-200KB and fires network requests. Ten scripts = 1-2MB of extra JavaScript + 20+ extra network requests.
- Audit every third-party script — remove ones nobody checks
- Use Google Tag Manager to lazy-load scripts after page load
- Replace heavy tools with lightweight alternatives (Plausible instead of GA4, Crisp instead of Intercom)
- Load non-critical scripts on user interaction (scroll, click) instead of page load
- Set a script budget: no more than 3-4 third-party scripts on marketing pages
Client-Side Rendering on Marketing Pages
This is the SaaS-specific trap. Your product is a web app built with React/Vue/Angular. So your marketing site uses the same framework. But marketing pages don't need client-side rendering — they're static content. CSR means the browser downloads JavaScript, executes it, and only then renders your page. Googlebot might not wait.
The real cost: We've measured LCP differences of 2-4 seconds between CSR and SSG for identical content. That's the difference between Google ranking you and ignoring you.
- Use SSG (Static Site Generation) for all marketing pages, blog posts, and documentation
- In Next.js: use
generateStaticParamsand avoid'use client'on marketing pages - Consider a separate static site for marketing (Astro, Hugo, plain HTML) decoupled from the app
- If stuck with CSR, implement server-side rendering (SSR) at minimum
No CDN or Poor Caching Headers
Some SaaS sites serve everything from a single origin server. No CDN means visitors in different regions get wildly different load times. And without proper cache headers, browsers re-download the same assets on every page visit.
- Deploy on a CDN (Vercel, Cloudflare Pages, Netlify, AWS CloudFront)
- Set
Cache-Control: public, max-age=31536000, immutablefor static assets (CSS, JS, images) - Use content hashing in filenames (e.g.,
app.a1b2c3.js) for safe long-term caching - Set shorter cache for HTML pages:
Cache-Control: public, max-age=3600, s-maxage=86400
Chat Widgets and Cookie Banners Causing CLS
Intercom, Drift, Crisp — they all inject floating elements that shift your page layout. Cookie consent banners that slide in from the bottom push your entire footer up. These micro-shifts add up and tank your CLS score.
- Reserve space for chat widgets with CSS (fixed positioning doesn't cause CLS, but the button appearing can)
- Use overlay-style cookie banners (positioned with
position: fixed) instead of banners that push content - Delay chat widget initialization by 3-5 seconds — most visitors don't need it immediately
- Pre-allocate space:
min-heighton sections where dynamic content will appear
How to Measure Your Core Web Vitals
Don't guess — measure. Here's the toolkit:
1. Google PageSpeed Insights
Go to pagespeed.web.dev and enter your URL. You get two types of data:
- Field data (real users) — from Chrome User Experience Report. This is what Google actually uses for ranking. Only available for sites with enough traffic.
- Lab data (simulated) — from Lighthouse. Useful for debugging but not what Google ranks on.
2. Google Search Console
The Core Web Vitals report in GSC groups your URLs into Good, Needs Improvement, and Poor. This is the most direct view of how Google sees your site speed. Check it monthly.
3. Chrome DevTools Performance Tab
For developers: open DevTools → Performance → Record a page load. You'll see exactly which resources block rendering, where layout shifts happen, and what causes slow interactions.
A Real-World Optimization Checklist
Use this checklist to systematically improve your SaaS site's Core Web Vitals:
Quick Wins (under 1 hour)
- Add
asyncordeferto all third-party<script>tags - Add
widthandheightattributes to all<img>tags - Add
loading="lazy"to images below the fold - Add
fetchpriority="high"to your hero/LCP image - Preload your primary web font
- Check for and remove unused third-party scripts
Medium Effort (1-4 hours)
- Convert images from PNG/JPG to WebP format
- Self-host Google Fonts
- Implement code splitting for JavaScript
- Move chat widget initialization to delayed loading
- Set up proper cache headers for static assets
- Add
<link rel="preconnect">for critical third-party origins
Significant Effort (1-2 weeks)
- Migrate marketing pages from CSR to SSG
- Deploy on a CDN if not already
- Implement responsive images with
<picture>andsrcset - Audit and reduce JavaScript bundle size by 50%+
- Implement route-based code splitting
The SEO Impact: What Faster Sites Actually Get
Speed isn't just a nice-to-have. Here's what the data shows:
- Ranking boost: Google has confirmed Core Web Vitals as a ranking signal. Sites that pass all three metrics have a measurable advantage, especially in competitive SERPs where content quality is similar.
- Lower bounce rate: A 1-second improvement in LCP reduces bounce rate by 7-12% on average.
- Better crawl efficiency: Faster sites get crawled more frequently by Googlebot. More pages indexed = more search visibility.
- Higher conversion rates: Shopify reported a 7% increase in conversion for every 100ms improvement in LCP. SaaS trial signups follow the same pattern.
SaaS-Specific Gotchas
A few things we see specifically on SaaS marketing sites that general speed guides miss:
Product Demo Embeds
Interactive product demos (Storylane, Navattic, Arcade) embed iframes that load their own JavaScript. Lazy-load these — use an IntersectionObserver to only load the iframe when it's about to scroll into view.
Pricing Page Calculators
Dynamic pricing calculators with sliders, toggles, and currency selectors often import heavy charting libraries. Load these on interaction, not on page load.
Customer Logo Carousels
20 high-res customer logos in a carousel = 20 image requests on page load. Use CSS sprites or inline SVGs. Even better: show 6 static logos and skip the carousel — they rarely engage visitors.
Video Testimonials
Embedding YouTube or Vimeo videos on your homepage adds 500KB+ of JavaScript from their players. Use lite-youtube-embed or similar — it loads a thumbnail first and only loads the player on click.
Not Sure Where Your Site Stands?
We'll audit your Core Web Vitals, find what's slowing you down, and give you a prioritized fix list — free.
Get Your Free Speed Audit →