`n

Lighthouse Score Improvement - Complete Guide

Published: September 25, 2024 | Reading time: 27 minutes

Lighthouse Score Overview

Improving Lighthouse scores is essential for better user experience and SEO:

Lighthouse Benefits
# Lighthouse Score Benefits
- Better user experience
- Improved SEO rankings
- Faster page loads
- Better accessibility
- Mobile optimization
- Core Web Vitals
- Performance insights

Performance Optimization

Core Web Vitals and Performance

Performance Optimization
# Performance Optimization Techniques

# 1. Image Optimization
// Next.js Image Component
import Image from 'next/image';

const OptimizedImage = ({ src, alt, width, height }) => {
  return (
    {alt}
  );
};

// WebP Image Support
const ImageWithWebP = ({ src, alt }) => {
  return (
    
      
      {alt}
    
  );
};

# 2. Code Splitting and Lazy Loading
import React, { lazy, Suspense } from 'react';

// Lazy load components
const HeavyComponent = lazy(() => import('./HeavyComponent'));
const ChartComponent = lazy(() => import('./ChartComponent'));

const App = () => {
  return (
    

My App

Loading...
}> Loading chart...
}>
); }; // Dynamic imports const loadModule = async () => { const module = await import('./heavyModule'); return module.default; }; # 3. Resource Hints // Preload critical resources // Prefetch next page resources // DNS prefetch # 4. Service Worker for Caching // sw.js const CACHE_NAME = 'my-app-cache-v1'; const urlsToCache = [ '/', '/static/css/main.css', '/static/js/main.js', '/images/logo.png' ]; self.addEventListener('install', (event) => { event.waitUntil( caches.open(CACHE_NAME) .then((cache) => cache.addAll(urlsToCache)) ); }); self.addEventListener('fetch', (event) => { event.respondWith( caches.match(event.request) .then((response) => { if (response) { return response; } return fetch(event.request); }) ); }); # 5. Critical CSS Inlining // Extract critical CSS const criticalCSS = ` body { margin: 0; font-family: Arial, sans-serif; } .header { background: #333; color: white; } .main { padding: 20px; } `; // Inline critical CSS const HTMLWithCriticalCSS = ` `n `; # 6. Bundle Optimization // webpack.config.js module.exports = { optimization: { splitChunks: { chunks: 'all', cacheGroups: { vendor: { test: /[\\/]node_modules[\\/]/, name: 'vendors', chunks: 'all' }, common: { name: 'common', minChunks: 2, chunks: 'all', enforce: true } } }, usedExports: true, sideEffects: false } }; # 7. Font Optimization // Font loading strategy const fontCSS = ` @font-face { font-family: 'CustomFont'; src: url('/fonts/custom-font.woff2') format('woff2'); font-display: swap; font-weight: 400; font-style: normal; } body { font-family: 'CustomFont', Arial, sans-serif; } `; // Preload fonts # 8. Third-party Script Optimization // Defer non-critical scripts // Use Intersection Observer for lazy loading const observer = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { const script = document.createElement('script'); script.src = entry.target.dataset.src; document.head.appendChild(script); observer.unobserve(entry.target); } }); }); document.querySelectorAll('[data-src]').forEach(el => { observer.observe(el); }); # 9. Performance Monitoring // Web Vitals measurement import { getCLS, getFID, getFCP, getLCP, getTTFB } from 'web-vitals'; function sendToAnalytics(metric) { // Send to analytics service gtag('event', metric.name, { value: Math.round(metric.value), event_label: metric.id, non_interaction: true }); } getCLS(sendToAnalytics); getFID(sendToAnalytics); getFCP(sendToAnalytics); getLCP(sendToAnalytics); getTTFB(sendToAnalytics); # 10. Performance Budget // performance-budget.js const performanceBudget = { maxBundleSize: 250 * 1024, // 250KB maxImageSize: 100 * 1024, // 100KB maxFontSize: 50 * 1024, // 50KB maxTotalSize: 1000 * 1024, // 1MB maxRequests: 50, maxRenderBlockingResources: 2 }; function checkPerformanceBudget(metrics) { const violations = []; if (metrics.bundleSize > performanceBudget.maxBundleSize) { violations.push(`Bundle size exceeds budget: ${metrics.bundleSize} > ${performanceBudget.maxBundleSize}`); } if (metrics.totalRequests > performanceBudget.maxRequests) { violations.push(`Request count exceeds budget: ${metrics.totalRequests} > ${performanceBudget.maxRequests}`); } return violations; }

Accessibility Optimization

Accessibility Best Practices

Accessibility Optimization
# Accessibility Optimization

# 1. Semantic HTML

Page Title

Page content goes here.

© 2024 My Website

# 2. ARIA Labels and Descriptions
This will close the current dialog and return to the main content.
We'll never share your email with anyone else.
Click to subscribe to our newsletter.
# 3. Focus Management // Focus management for modals class Modal { constructor(element) { this.element = element; this.previousFocus = null; this.focusableElements = this.element.querySelectorAll( 'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])' ); } open() { this.previousFocus = document.activeElement; this.element.style.display = 'block'; this.element.setAttribute('aria-hidden', 'false'); // Focus first focusable element this.focusableElements[0].focus(); // Trap focus this.element.addEventListener('keydown', this.handleKeyDown.bind(this)); } close() { this.element.style.display = 'none'; this.element.setAttribute('aria-hidden', 'true'); // Return focus to previous element if (this.previousFocus) { this.previousFocus.focus(); } this.element.removeEventListener('keydown', this.handleKeyDown.bind(this)); } handleKeyDown(event) { if (event.key === 'Escape') { this.close(); } else if (event.key === 'Tab') { const firstElement = this.focusableElements[0]; const lastElement = this.focusableElements[this.focusableElements.length - 1]; if (event.shiftKey) { if (document.activeElement === firstElement) { event.preventDefault(); lastElement.focus(); } } else { if (document.activeElement === lastElement) { event.preventDefault(); firstElement.focus(); } } } } } # 4. Color Contrast // CSS with proper contrast ratios :root { --primary-color: #0066cc; /* 4.5:1 contrast ratio */ --secondary-color: #333333; /* 4.5:1 contrast ratio */ --background-color: #ffffff; --text-color: #000000; /* 21:1 contrast ratio */ --error-color: #d32f2f; /* 4.5:1 contrast ratio */ } .button { background-color: var(--primary-color); color: var(--background-color); border: 2px solid var(--primary-color); } .button:hover { background-color: var(--background-color); color: var(--primary-color); } .button:focus { outline: 2px solid var(--primary-color); outline-offset: 2px; } # 5. Screen Reader Support // Screen reader only content .sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; } // Skip links .skip-link { position: absolute; top: -40px; left: 6px; background: var(--primary-color); color: white; padding: 8px; text-decoration: none; z-index: 1000; } .skip-link:focus { top: 6px; } # 6. Form Accessibility
Contact Information
Include country code if outside US.
Preferred Contact Method
# 7. Image Accessibility // Decorative images // Informative images Sales increased by 25% in Q3 2024 compared to Q2 2024
A bar chart showing quarterly sales data. Q1: $100k, Q2: $120k, Q3: $150k. The chart shows a steady increase in sales throughout the year.
// Complex images
Company growth infographic
Our company has grown from 10 employees in 2020 to 100 employees in 2024, with revenue increasing from $1M to $10M over the same period.
# 8. Keyboard Navigation // Custom keyboard navigation class KeyboardNavigation { constructor(container) { this.container = container; this.focusableElements = container.querySelectorAll( 'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])' ); this.currentIndex = 0; } init() { this.container.addEventListener('keydown', this.handleKeyDown.bind(this)); } handleKeyDown(event) { switch (event.key) { case 'ArrowDown': case 'ArrowRight': event.preventDefault(); this.focusNext(); break; case 'ArrowUp': case 'ArrowLeft': event.preventDefault(); this.focusPrevious(); break; case 'Home': event.preventDefault(); this.focusFirst(); break; case 'End': event.preventDefault(); this.focusLast(); break; } } focusNext() { this.currentIndex = (this.currentIndex + 1) % this.focusableElements.length; this.focusableElements[this.currentIndex].focus(); } focusPrevious() { this.currentIndex = this.currentIndex === 0 ? this.focusableElements.length - 1 : this.currentIndex - 1; this.focusableElements[this.currentIndex].focus(); } focusFirst() { this.currentIndex = 0; this.focusableElements[0].focus(); } focusLast() { this.currentIndex = this.focusableElements.length - 1; this.focusableElements[this.currentIndex].focus(); } } # 9. Live Regions // Announce dynamic content changes
function updateStatus(message) { const statusElement = document.getElementById('status'); statusElement.textContent = message; } // Use assertive for urgent updates
function showAlert(message) { const alertElement = document.getElementById('alert'); alertElement.textContent = message; } # 10. Accessibility Testing // Automated accessibility testing const axe = require('axe-core'); function runAccessibilityTests() { axe.run(document, (err, results) => { if (err) throw err; console.log('Accessibility violations:', results.violations); results.violations.forEach(violation => { console.log(`Rule: ${violation.id}`); console.log(`Description: ${violation.description}`); console.log(`Impact: ${violation.impact}`); console.log(`Nodes: ${violation.nodes.length}`); }); }); } // Manual testing checklist const accessibilityChecklist = { keyboard: [ 'All interactive elements are keyboard accessible', 'Tab order is logical and intuitive', 'Focus indicators are visible', 'No keyboard traps' ], screenReader: [ 'All content is accessible to screen readers', 'Images have appropriate alt text', 'Form labels are properly associated', 'Headings are properly structured' ], visual: [ 'Color contrast meets WCAG standards', 'Content is readable without color', 'Text can be resized up to 200%', 'No content flashes more than 3 times per second' ] };

SEO Optimization

SEO Best Practices

Lighthouse Categories

  • Performance
  • Accessibility
  • Best Practices
  • SEO
  • Progressive Web App

Optimization Areas

  • Core Web Vitals
  • Image optimization
  • Code splitting
  • Resource hints
  • Caching strategies
  • Semantic HTML
  • ARIA attributes

Summary

Lighthouse score improvement involves several key areas:

Need More Help?

Struggling with Lighthouse scores or need help optimizing your website performance? Our frontend experts can help you achieve better scores and improve user experience.

Get Lighthouse Help