Top 10 Lighthouse Audit Failures and How to Fix Them
The most common Lighthouse audit failures and step-by-step instructions to fix each one. Covers performance, accessibility, and best practices.
Lighthouse audits flag dozens of issues, but a handful appear on almost every site. Here are the 10 most common failures and exactly how to fix each one.
1. "Serve images in next-gen formats"
What it means: You're serving JPEG or PNG images when WebP or AVIF would be 25-50% smaller.
How to fix:
<!-- Use the <picture> element for format fallbacks -->
<picture>
<source srcset="image.avif" type="image/avif">
<source srcset="image.webp" type="image/webp">
<img src="image.jpg" alt="Description" width="800" height="600">
</picture>
Or use a build tool:
# Convert with sharp-cli
npx sharp-cli --input images/*.jpg --output images/ --format webp --quality 80
Impact: Medium-High (reduces transfer size significantly)
2. "Properly size images"
What it means: Images are larger (in pixels) than they're displayed. A 3000×2000 image displayed at 300×200 wastes bandwidth.
How to fix:
<!-- Use srcset for responsive images -->
<img
srcset="image-400.webp 400w,
image-800.webp 800w,
image-1200.webp 1200w"
sizes="(max-width: 600px) 100vw, 800px"
src="image-800.webp"
alt="Description"
width="800"
height="600"
>
Rule: Serve images at 2x display size maximum (for retina).
Impact: High (oversized images are often the #1 performance issue)
3. "Eliminate render-blocking resources"
What it means: CSS and JavaScript files in <head> block the page from rendering until they download and execute.
How to fix:
<!-- Defer non-critical JavaScript -->
<script src="analytics.js" defer></script>
<!-- Async for independent scripts -->
<script src="widget.js" async></script>
<!-- Preload critical CSS, lazy load the rest -->
<link rel="preload" href="critical.css" as="style">
<link rel="stylesheet" href="non-critical.css" media="print" onload="this.media='all'">
Impact: High (directly affects FCP and LCP)
4. "Reduce unused JavaScript"
What it means: JavaScript is being downloaded but not executed on this page.
How to fix:
- Use code splitting to load only needed code per route
- Remove unused npm packages
- Use dynamic imports for heavy components:
// Instead of importing everything
const HeavyChart = dynamic(() => import('./HeavyChart'), {
loading: () => <p>Loading chart...</p>,
ssr: false,
});
Impact: High (unused JS still needs download, parse, compile)
5. "Image elements do not have explicit width and height"
What it means: Images without dimensions cause layout shifts (CLS) as they load.
How to fix:
<!-- Always include width and height -->
<img src="photo.webp" alt="Photo" width="800" height="600">
<!-- Or use CSS aspect-ratio -->
<style>
.hero-image {
aspect-ratio: 16/9;
width: 100%;
height: auto;
}
</style>
Impact: Medium (directly fixes CLS)
6. "Avoid enormous network payloads"
What it means: Total page weight exceeds 5MB. Slow on mobile connections.
How to fix:
- Compress images (WebP/AVIF)
- Minify CSS and JavaScript
- Enable Brotli/Gzip compression
- Remove unused code and assets
- Lazy load below-fold content
Target: Keep total page weight under 1.5MB for optimal performance.
Impact: High (affects all metrics on slow connections)
7. "Minimize main-thread work"
What it means: Too much JavaScript executing on the main thread, blocking user interactions.
How to fix:
- Break up long tasks (>50ms) into smaller chunks
- Move heavy computation to Web Workers
- Reduce JavaScript bundle size
- Defer non-critical scripts
- Use
requestIdleCallbackfor low-priority work
// Break long task with scheduler
function processItems(items) {
const chunk = items.splice(0, 100);
chunk.forEach(process);
if (items.length > 0) {
requestIdleCallback(() => processItems(items));
}
}
Impact: High (directly affects TBT and INP)
8. "Ensure text remains visible during webfont load"
What it means: Custom fonts cause invisible text (FOIT) until they download.
How to fix:
@font-face {
font-family: 'CustomFont';
src: url('font.woff2') format('woff2');
font-display: swap; /* Show fallback font immediately */
}
Impact: Medium (affects FCP and perceived performance)
9. "Avoid an excessive DOM size"
What it means: Page has too many HTML elements (>1,500 nodes). Common with page builders.
How to fix:
- Simplify HTML structure
- Remove unnecessary wrapper divs
- Virtualize long lists
- Lazy load complex sections
Impact: Medium (affects memory, style calculation, and layout)
10. "Reduce the impact of third-party code"
What it means: Third-party scripts (analytics, chat, ads) are using significant resources.
How to fix:
- Audit all third-party scripts (do you need all of them?)
- Load non-critical scripts after page load
- Use
loading="lazy"for embedded content (YouTube, maps) - Self-host critical third-party resources
<!-- Lazy load YouTube embeds -->
<iframe
src="https://www.youtube.com/embed/VIDEO_ID"
loading="lazy"
width="560" height="315"
title="Video title"
></iframe>
Impact: High (third-party code is often 50-70% of total JS)
Fix Priority Order
- Properly size images → Biggest bandwidth savings
- Serve next-gen formats → Easy win with big impact
- Eliminate render-blocking → Unlocks faster rendering
- Reduce unused JavaScript → Lower TBT
- Add image dimensions → Fix CLS
- Font display → Fix FOIT
- Reduce network payload → Overall improvement
- Minimize main-thread → Better interactivity
- Third-party impact → Often neglected
- DOM size → Architecture issue
Monitor Your Audit Results
BadPageSpeed runs Lighthouse audits on a schedule so you can track these issues over time.
Ready to stop wasting ad spend?
Track your landing page performance, monitor Core Web Vitals, and calculate exactly how much slow pages cost you.
Start Free — No Credit Card