Lighthouse Score 100: A Practical Step-by-Step Guide
Getting a perfect Lighthouse score isn't magic. It's a systematic process of eliminating render-blocking resources, optimizing assets, and fixing accessibility gaps.
A perfect Lighthouse score isn't the goal — a fast, accessible website is. But Lighthouse 100 is a useful forcing function that makes you address every category: Performance, Accessibility, Best Practices, and SEO. I've hit 100 across all four on three production Next.js sites, and the process is more systematic than you'd think.
Performance: The Hardest 100
Performance scoring is weighted: Largest Contentful Paint (25%), Cumulative Layout Shift (25%), Total Blocking Time (30%), First Contentful Paint (10%), Speed Index (10%). Focus on TBT and LCP first — they account for 55% of the score.
Eliminate render-blocking resources. Move non-critical CSS to async loading. Defer third-party scripts. Inline critical CSS for above-the-fold content:
// next.config.ts — enable CSS optimization
const config: NextConfig = {
experimental: {
optimizeCss: true, // Inlines critical CSS
},
};
// layout.tsx — defer non-critical scripts
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
{children}
{/* Analytics loaded after page is interactive */}
<Script
src="https://analytics.example.com/script.js"
strategy="lazyOnload"
/>
</body>
</html>
);
}
Optimize LCP. Identify your LCP element (usually the hero image or main heading). Add priority to hero images. Preconnect to external image domains. Ensure the LCP element doesn't depend on JavaScript to render.
Fix CLS. Set explicit dimensions on images and embeds. Use CSS aspect-ratio for responsive containers. Reserve space for dynamic content (ads, lazy-loaded components) with min-height.
Accessibility: Often Overlooked, Easy to Fix
Most accessibility issues are mechanical fixes:
- Add
alttext to every image (decorative images getalt="") - Ensure color contrast ratio of 4.5:1 for normal text, 3:1 for large text
- Add
aria-labelto icon-only buttons - Ensure all interactive elements are keyboard-navigable
- Use semantic HTML:
<main>,<nav>,<article>,<section>with headings
// ❌ Accessibility failures
<div onClick={handleClick}>Click me</div>
<img src="/hero.jpg" />
<button><SearchIcon /></button>
// ✅ Accessible equivalents
<button onClick={handleClick}>Click me</button>
<img src="/hero.jpg" alt="Developer workspace with dual monitors" />
<button aria-label="Search"><SearchIcon aria-hidden="true" /></button>
Best Practices: Quick Wins
- Serve all assets over HTTPS
- Add CSP headers and other security headers
- Avoid
document.write()and deprecated APIs - Ensure no console errors in production
- Use HTTP/2 or HTTP/3
SEO: The Easiest 100
Next.js handles most SEO requirements through the Metadata API:
- Export
metadataorgenerateMetadatafrom every page - Include title, description, Open Graph, and canonical URL
- Add structured data (JSON-LD) for articles and organization
- Generate
sitemap.xmlandrobots.txt - Ensure every page is reachable via internal links
The Process
- Run Lighthouse in Incognito mode (extensions affect scores)
- Address Performance issues first — they're the hardest
- Fix Accessibility — usually 10–15 mechanical fixes
- Clean up Best Practices — mostly security headers
- Verify SEO — metadata and structured data
- Re-run and iterate — some fixes affect multiple categories
Takeaways
- Focus on TBT and LCP — they're 55% of the Performance score
- Defer all non-critical scripts and inline critical CSS
- Accessibility fixes are mechanical — semantic HTML and ARIA attributes
- Use the Next.js Metadata API for SEO — it handles most requirements automatically
- Run Lighthouse in Incognito to get accurate, reproducible scores
Admin
Cal.com
Open source scheduling — tự host booking system, thay thế Calendly. Free & privacy-first.
Bình luận (0)
Đăng nhập để bình luận
Chưa có bình luận nào. Hãy là người đầu tiên!