Why all four Lighthouse metrics matter
Google Lighthouse scores your website on four metrics: Performance, Accessibility, Best Practices, and SEO. Most developers focus on Performance and ignore the rest. That's a mistake.
In our previous articles, we covered Performance optimization in detail—how to achieve 100/100 on PageSpeed and why professional websites often score poorly. Those techniques handle the Performance pillar.
This guide completes the picture. We'll cover the three remaining pillars: SEO, Accessibility, and Best Practices. Together with the Performance techniques from our earlier articles, you'll have everything needed to achieve 100/100 across all four metrics.
Why all four matter:
- Performance affects load times and user experience
- SEO determines whether Google can find and rank your site
- Accessibility ensures everyone can use your site, including people with disabilities
- Best Practices covers security, modern standards, and technical correctness
On every demo site we've built, SEO, Accessibility, and Best Practices score 100/100—no exceptions. Performance occasionally dips a few points on mobile (Nuxt overhead, Cloudflare scripts), but typically hits 100 as well. Seven out of eight scores are always perfect; often all eight are. This guide documents exactly how.
SEO: Making Your Site Discoverable
The Foundation Files
Before Google indexes your site, it checks two files: robots.txt and sitemap.xml. Missing these doesn't break your site, but it slows discovery significantly.
robots.txt tells crawlers which pages to index. Place it at your site root:
User-agent: *
Allow: /
Sitemap: https://yoursite.com/sitemap.xml
Common mistakes:
- Using
Disallow: /(blocks all crawlers—your site won't be indexed) - Forgetting the sitemap reference
- Wrong file location (must be at root, not in a subfolder)
sitemap.xml maps all your pages. For small sites, write it manually:
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>https://yoursite.com/</loc>
<lastmod>2025-12-07</lastmod>
<priority>1.0</priority>
</url>
<url>
<loc>https://yoursite.com/about</loc>
<priority>0.8</priority>
</url>
</urlset>
Strategy tip: Less is more. Don't index everything. Your Terms of Service page doesn't need to rank. A focused sitemap with strong pages beats a bloated one with thin content.
Meta Tags That Matter
Search engines and social platforms read specific HTML tags. Missing these means broken-looking links when shared.
Essential tags in your <head>:
<!-- Page basics -->
<html lang="en">
<title>Your Page Title - Under 60 Characters</title>
<meta name="description" content="150-160 characters. Shows in search results.">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="canonical" href="https://yoursite.com/page-url">
<!-- Open Graph (Facebook, LinkedIn, Slack) -->
<meta property="og:title" content="Your Page Title">
<meta property="og:description" content="Same as meta description">
<meta property="og:url" content="https://yoursite.com/page-url">
<meta property="og:image" content="https://yoursite.com/og-image.jpg">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta property="og:type" content="website">
<!-- Twitter/X -->
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="Your Page Title">
<meta name="twitter:image" content="https://yoursite.com/og-image.jpg">
Why these matter:
- Title and description: What appears in Google search results
- Canonical URL: Prevents duplicate content issues
- Open Graph: Controls how links appear when shared on social platforms
lang="en": Required for accessibility—tells screen readers which language to use
Common mistakes:
- Title over 60 characters (Google truncates with "...")
- Missing OG image dimensions (Facebook won't show preview)
- Forgetting the
langattribute on<html>(fails Lighthouse accessibility check)
Structured Data (JSON-LD)
Structured data tells Google what type of content you have, enabling rich results in search:
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Organization",
"name": "Your Company",
"url": "https://yoursite.com",
"logo": "https://yoursite.com/logo.png",
"sameAs": [
"https://twitter.com/yourcompany",
"https://linkedin.com/company/yourcompany"
]
}
</script>
Other useful types: Person (portfolios), LocalBusiness (physical locations), Article (blog posts), FAQPage (can display directly in search results).
Testing: Use Google's Rich Results Test to validate your JSON-LD.
Google Search Console Setup
After deploying, verify your site with Google Search Console:
- Add your domain
- Verify via DNS TXT record or meta tag
- Submit your sitemap URL
- Request indexing for important pages
Expect 1-2 weeks before pages appear in search results. Use Search Console to monitor progress.
Cloudflare Users: Check Scrape Shield
If you're on Cloudflare, check your Scrape Shield settings. The default "Email Address Obfuscation" injects a 500ms render-blocking script into every page. We lost 8 points on multiple demos before catching this.
Fix: Security → Scrape Shield → Disable "Email Address Obfuscation"
Accessibility: Building for Everyone
Accessibility isn't charity—it's good engineering. An accessible site works better for everyone: keyboard users, screen reader users, people with slow connections, and users on mobile devices.
Semantic HTML Structure
Lighthouse checks for proper HTML landmarks. Missing these fails the accessibility audit.
Required landmarks:
<header>
<nav><!-- Navigation here --></nav>
</header>
<main>
<!-- All primary content MUST be inside <main> -->
<article>
<h1>Page Title</h1>
<!-- Content -->
</article>
</main>
<footer>
<!-- Footer content -->
</footer>
The <main> element is critical. Lighthouse specifically checks for it. Screen readers use it to skip navigation and jump directly to content.
Heading Hierarchy
Use one <h1> per page. Follow logical order: h1 → h2 → h3. Never skip levels (no h1 → h3).
Why this matters: Screen reader users navigate by headings. Skipped levels confuse navigation. Headings should describe content structure, not just style text.
Color Contrast
WCAG AA requires minimum contrast ratios:
- Normal text (< 18px): 4.5:1 contrast ratio
- Large text (≥ 18px or ≥ 14px bold): 3:1 contrast ratio
- UI components (buttons, form borders): 3:1 contrast ratio
Links require special attention. Color alone isn't sufficient to distinguish links from surrounding text. Use underlines or other visual indicators.
Testing: Chrome DevTools → Inspect element → Accessibility tab shows contrast ratios. Or use WebAIM Contrast Checker.
Image Alt Text
Every image needs an alt attribute:
<!-- Meaningful image: describe the content -->
<img src="team-photo.jpg" alt="CodeCrank team at the 2025 developer conference">
<!-- Decorative image: use empty alt (not missing) -->
<img src="decorative-line.svg" alt="">
Common mistakes:
- Missing alt attributes entirely (fails audit)
- Using "image of..." prefix (redundant—screen readers already announce it's an image)
- Empty alt on meaningful images (screen readers skip them entirely)
Form Accessibility
Every input needs an associated label:
<!-- Correct: label linked via 'for' attribute -->
<label for="email">Email Address</label>
<input type="email" id="email" name="email">
<!-- Also correct: input nested inside label -->
<label>
Email Address
<input type="email" name="email">
</label>
For required fields, don't rely on asterisks alone. Use the required attribute and aria-required="true".
Interactive Elements
Buttons and links need accessible names. Icon-only buttons need ARIA labels:
<!-- Icon button: needs aria-label -->
<button aria-label="Open menu">
<svg><!-- hamburger icon --></svg>
</button>
<!-- Decorative icons: hide from screen readers -->
<span aria-hidden="true">★</span> 4.8 rating
Keyboard navigation: All interactive elements must be reachable via Tab key. Focus indicators must be visible (don't remove outlines without providing alternatives).
Best Practices: Security and Standards
Best Practices covers security, modern web standards, and technical correctness. Most failures here are easy to fix.
HTTPS Everywhere
Serve all content over HTTPS. No mixed content (HTTP resources on HTTPS pages). Modern hosting platforms handle this automatically.
Safe External Links
External links should use rel="noopener":
<a href="https://external-site.com" target="_blank" rel="noopener">
External Link
</a>
This prevents the external page from accessing your window.opener object—a security vulnerability. Lighthouse flags links missing this attribute.
No Console Errors
Open DevTools Console before deploying. Fix all errors. Common culprits:
- Missing resources (404s for images, scripts, fonts)
- JavaScript errors from typos or undefined variables
- Deprecated API warnings
Zero tolerance: Any console error can fail the Best Practices audit.
Image Aspect Ratios
Images need explicit dimensions to prevent layout shift:
<img src="photo.jpg" width="1200" height="800" alt="Description">
Or use CSS aspect-ratio:
img {
width: 100%;
height: auto;
aspect-ratio: 3/2;
}
This prevents Cumulative Layout Shift (CLS) and satisfies Best Practices requirements for proper image sizing.
Modern Standards
Avoid deprecated APIs:
- Use
fetch()instead ofXMLHttpRequest - Use
addEventListener()instead of inlineonclickattributes - Never use
document.write()
Icons and Favicons
The finishing touches that make your site look complete:
Required files:
favicon.ico(32×32, legacy browsers)favicon.svg(scalable, modern browsers)apple-touch-icon.png(180×180, iOS home screen)icon-192.pngandicon-512.png(Android, PWA)
HTML tags:
<link rel="icon" href="/favicon.ico" sizes="32x32">
<link rel="icon" href="/favicon.svg" type="image/svg+xml">
<link rel="apple-touch-icon" href="/apple-touch-icon.png">
<link rel="manifest" href="/manifest.json">
Missing favicons don't fail Lighthouse, but they make your site look unfinished. Some browsers show broken icons, others show nothing.
Tool: RealFaviconGenerator.net generates all sizes from one image.
The Complete Checklist
Performance (covered in Article 1 & Article 2):
- Critical CSS inlining
- AVIF/WebP images with explicit dimensions
- Deferred JavaScript loading
- Zero layout shift
SEO:
- robots.txt and sitemap.xml
- Title, description, canonical URL
- Open Graph and Twitter meta tags
- Structured data (JSON-LD)
- Google Search Console verification
Accessibility:
- Semantic HTML landmarks (<main>, <nav>, <header>, <footer>)
- Proper heading hierarchy (single h1, no skipped levels)
- WCAG color contrast (4.5:1 for text)
- Alt text on all images
- Form labels properly associated
- ARIA labels for icon buttons
Best Practices:
- HTTPS everywhere
rel="noopener"on external links- Zero console errors
- Explicit image dimensions
- No deprecated APIs
The Expert Take
On every demo in our portfolio, SEO, Accessibility, and Best Practices hit 100/100. Performance usually does too, though it occasionally dips a few points on mobile due to framework overhead or CDN scripts. You can verify this yourself—click "PageSpeed Me" on any of our sites.
Time investment: First-time setup takes 4-6 hours. Once you know the patterns, subsequent sites take 1-2 hours.
Most agencies don't publish their Lighthouse scores. We put a verification button on every site we build. The work should speak for itself.
My side business DCTSoft builds custom websites for small businesses in record time, implementing all these techniques and often achieving perfect scores across the board.
This completes our PageSpeed series. For performance optimization techniques, see How to Achieve 100/100 on PageSpeed.