Core Web Vitals and Ads
Understand how ads affect your Core Web Vitals — and how to minimize the impact.
What are Core Web Vitals?
Core Web Vitals (CWV) are Google's metrics for measuring user experience:
| Metric | Measures | Good | Needs work | Poor |
|---|---|---|---|---|
| LCP (Largest Contentful Paint) | Loading | < 2.5s | 2.5-4s | > 4s |
| INP (Interaction to Next Paint) | Interactivity | < 200ms | 200-500ms | > 500ms |
| CLS (Cumulative Layout Shift) | Visual stability | < 0.1 | 0.1-0.25 | > 0.25 |
These metrics affect:
- Google rankings — CWV is a ranking factor
- User experience — Correlates with engagement and bounce rate
- Ad performance — Slow pages have lower viewability
How ads affect each metric
LCP (Largest Contentful Paint)
What it measures: Time until the largest content element loads.
How ads hurt LCP:
- Ad-related network requests compete with LCP-critical resources for bandwidth
- Large ad creatives take time to load and can become the LCP element themselves
- Content-pushing layout (ad loads above content) delays the visual LCP
The fix:
| Strategy | Impact |
|---|---|
Keep the wrapper tag near the top of <head> | The inline IIFE loader is designed to kick off library + config fetches at priority: 'low' — non-blocking already. Don't wrap it in a blocking guard (consent gate, A/B test) that defers it past LCP. |
| Lazy-load below-fold slots | Only above-fold ads can affect LCP |
| Tighten wrapper bid timeout | Shorter wait = faster auction-to-render |
Use fetchpriority for content | Prioritize content over ads |
INP (Interaction to Next Paint)
What it measures: Responsiveness when user interacts.
How ads hurt INP:
- Ad scripts consume CPU
- Rich media ads (video, animations) compete for resources
- Too many ads = more JavaScript execution
The fix:
| Strategy | Impact |
|---|---|
| Limit rich media formats | Less CPU competition |
| Defer non-critical ad scripts | Main thread stays responsive |
| Reduce total ad count | Less JavaScript overall |
CLS (Cumulative Layout Shift)
What it measures: How much content shifts during load.
How ads hurt CLS:
- Ads load after content, pushing it down
- Different ad sizes cause different shifts
- Late-loading ads inject into content flow
The fix:
| Strategy | Impact |
|---|---|
| Reserve space for ads | No shift when ads load |
| Use fixed ad sizes | Predictable dimensions |
| Avoid injected ads | Place ads in designed slots |
| Load ads early | Shift happens before user sees it |
Measuring ad impact on CWV
In Anima
If CWV tracking is enabled:
- Go to Dashboard → Core Web Vitals
- View metrics by:
- Page type
- Device
- Ad configuration
- Compare pages with/without specific ad setups
In Google Search Console
- Go to Core Web Vitals report
- Review "Poor URLs" and "Needs improvement"
- Cross-reference with pages that have more ads
In Chrome DevTools
- Open DevTools (F12)
- Go to Lighthouse tab
- Run audit with "Performance" checked
- Review CWV scores and diagnostics
Best practices by metric
Optimizing for LCP
Target: LCP < 2.5s even with ads loading.
The wrapper tag is an inline IIFE, not a hosted <script src=…>. It loads the per-domain library from jsDelivr and the config from the Portal API in parallel, both at priority: 'low'. For the full architecture, see Wrapper Debugging.
Optimizing for CLS
The key: Reserve space before ads load.
<!-- BAD: No reserved space -->
<div class="ad-container">
<!-- Ad loads here, pushes content down -->
</div>
<!-- GOOD: Reserved space -->
<div class="ad-container" style="min-height: 250px; min-width: 300px;">
<!-- Ad loads into reserved space, no shift -->
</div>
For each ad slot:
- Define the maximum size that could load
- Set
min-heightandmin-widthin CSS - Consider using aspect ratio containers
For responsive ads:
.ad-container {
min-height: 250px;
aspect-ratio: 300 / 250;
contain: layout;
}
Optimizing for INP
Reduce JavaScript weight:
- Enable only necessary ad features
- Avoid heavy rich media on slow devices
- Consider lighter ad formats for mobile
Defer non-critical scripts:
<script defer src="analytics.js"></script>
<script defer src="optional-features.js"></script>
Configuration recommendations
Above-the-fold slots
| Setting | Recommendation | Why |
|---|---|---|
| Lazy loading | OFF | Needs to load for LCP |
| Reserved space | YES | Prevents CLS |
| Sizes | Limited (1-2) | Predictable dimensions |
| Priority | High | Part of initial render |
Below-the-fold slots
| Setting | Recommendation | Why |
|---|---|---|
| Lazy loading | ON | Doesn't affect LCP |
| Reserved space | YES | Still prevents CLS |
| Sizes | More flexible | Doesn't affect initial load |
| Priority | Normal | Can wait |
Mobile-specific
| Setting | Recommendation |
|---|---|
| Fewer slots | 3-4 max per page |
| Smaller sizes | 320x50, 300x250 |
| Simpler formats | Avoid heavy video |
| Aggressive lazy | Only visible ads |
Testing your setup
Pre-deployment testing
-
Lighthouse audit:
- Run on pages with ads
- Check CWV scores
- Review diagnostics
-
WebPageTest:
- Test real devices
- Film strip view shows shift
- Waterfall shows blocking
-
Chrome DevTools Performance:
- Record page load
- Identify layout shifts
- Find long tasks
A/B testing CWV impact
Create experiments to test:
| Experiment | Control | Variation |
|---|---|---|
| Lazy loading | Off for all | On for below-fold |
| Slot count | 6 slots | 4 slots |
| Timeout | 1500ms | 1000ms |
| Reserved space | None | All slots |
Measure both CWV and revenue to find optimal balance.
Common CWV issues and fixes
Issue: LCP > 4 seconds
Diagnose: Is the largest element an ad or content?
- If ad: Your ad is loading before content (bad)
- If content: Ads may be blocking content load
Fix:
- Ensure wrapper loads async
- Prioritize content with
fetchpriority="high" - Lazy load all below-fold ads
- Reduce timeout
Issue: CLS > 0.25
Diagnose: Where is the shift happening?
- Use Chrome DevTools → Performance → Experience
- Look for layout shift entries
Fix:
- Add reserved space for all ad containers
- Use fixed sizes instead of responsive
- Load ads earlier if possible
- Avoid injecting ads dynamically
Issue: INP > 500ms
Diagnose: What's blocking the main thread?
- DevTools → Performance → Main thread
- Look for long tasks during interaction
Fix:
- Reduce number of ad scripts
- Disable heavy ad formats
- Defer non-critical scripts
- Consider fewer demand partners
Balancing CWV and revenue
The goal isn't perfect CWV scores — it's good enough CWV with optimal revenue.
| CWV Status | Action |
|---|---|
| All green (good) | You have room to add monetization |
| Yellow (needs work) | Optimize before adding more |
| Red (poor) | Fix CWV before anything else |
The revenue check
Before any CWV optimization:
- Measure current revenue per pageview
- Make CWV changes
- Measure new revenue per pageview
If revenue drops significantly, the CWV improvement may not be worth it. Find a better solution.
Related resources
- Revenue vs. Latency → — Broader optimization framework
- Lazy Loading → — Implementation details
- Experiments → — Testing CWV changes
- Google's CWV documentation — Official guidance