阿里云主机折上折
  • 微信号
Current Site:Index > Lighthouse score: from 60 to 90, how many hairs did I lose?

Lighthouse score: from 60 to 90, how many hairs did I lose?

Author:Chuan Chen 阅读数:51588人阅读 分类: 前端综合

Going from a 60 to a 90 Lighthouse score is a hard-fought battle involving performance, accessibility, SEO, and best practices. The pitfalls encountered, the late nights spent, and the hair lost along the way ultimately crystallized into these实战经验 (practical insights).

Performance Optimization: From Snail-Paced Loading to Lightning-Fast Response

Low performance scores often stem from resource loading and render-blocking issues. A classic example is unoptimized images and uncompressed JavaScript. For instance, an e-commerce homepage might be packed with high-resolution product images:

<!-- Poor implementation -->
<img src="product-huge.jpg" alt="Product image">

The solution is to use modern image formats and lazy loading:

<!-- Optimized version -->
<img 
  src="product.webp" 
  srcset="product-small.webp 480w, product-medium.webp 1024w"
  sizes="(max-width: 600px) 480px, 1024px"
  loading="lazy"
  alt="Product image"
>

JavaScript optimization is even more critical. In one case, a third-party library accounted for 70% of the bundle size:

// Original code: Importing the entire lodash library
import _ from 'lodash';
_.debounce(handler, 300);

// Optimized: Tree-shaking and selective imports
import debounce from 'lodash/debounce';
debounce(handler, 300);

Accessibility: More Than Just a Gift to Screen Readers

Low accessibility scores often result from overlooked ARIA attributes and color contrast. A common mistake is custom buttons:

<!-- Problematic code -->
<div class="btn" onclick="submit()">Submit</div>

Screen readers won’t recognize this as a button. The fix:

<button class="btn" aria-label="Submit order">Submit</button>

Color contrast issues are more insidious. Once, a designer’s chosen primary color #FF7E7E had a contrast ratio of only 3.2:1 against white (WCAG requires at least 4.5:1). The solution was to adjust after testing with tools:

/* Before */
.button {
  background-color: #FF7E7E;
  color: white;
}

/* After */
.button {
  background-color: #E74C3C; /* 5.92:1 contrast ratio */
  color: white;
}

SEO: Making Your Hard Work Visible to Crawlers

Low SEO scores often stem from missing metadata and semantic tags. A news site might write headlines like this:

<!-- Poor practice -->
<div class="title">Latest Pandemic Updates</div>

The optimized version uses semantic tags and structured data:

<h1 itemscope itemtype="https://schema.org/NewsArticle">
  <span itemprop="headline">Latest Pandemic Updates</span>
</h1>
<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "NewsArticle",
  "headline": "Latest Pandemic Updates"
}
</script>

Best Practices: The Devil’s in the Details

Best-practice deductions often involve security policies and modern APIs. For example, missing CSP headers trigger console warnings:

# Original response header
Content-Security-Policy: default-src 'self'

A more robust policy looks like this:

Content-Security-Policy: 
  default-src 'self';
  script-src 'self' 'unsafe-inline' cdn.example.com;
  style-src 'self' 'unsafe-inline';
  img-src 'self' data:;

Another frequent issue is outdated APIs. One page used document.write to load ads:

// Legacy approach
document.write('<script src="ads.js"></script>');

// Modern alternative
const script = document.createElement('script');
script.src = 'ads.js';
document.body.append(script);

Debugging Tools: Advanced Chrome DevTools Techniques

Lighthouse audits require deeper analysis with DevTools. The Network panel can identify unused CSS:

/* Dead code */
.old-banner { display: none; }

The Performance panel captures layout thrashing. A recording revealed an animation causing continuous reflows:

// Problem: Synchronous layout reads
function animate() {
  element.style.left = element.offsetLeft + 1 + 'px';
  requestAnimationFrame(animate);
}

// Fix: Use transform to avoid reflows
function animate() {
  element.style.transform = `translateX(${x++}px)`;
  requestAnimationFrame(animate);
}

Continuous Monitoring: Making Optimization Routine

One-time fixes aren’t enough—establish monitoring. Automate Lighthouse checks via GitHub Actions:

# .github/workflows/lighthouse.yml
name: Lighthouse Audit
on: [push]
jobs:
  audit:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: treosh/lighthouse-ci-action@v8
        with:
          urls: |
            https://example.com
            https://example.com/pricing
          budgetPath: ./lighthouse-budget.json

Example budget file:

{
  "performance": 90,
  "accessibility": 95,
  "seo": 90,
  "best-practices": 90
}

The Head-Scratching Edge Cases

The trickiest issue was font loading causing layout shifts. After one optimization, the CLS (Cumulative Layout Shift) score dropped:

/* Root cause: Fallback font metrics mismatch */
body {
  font-family: 'CustomFont', Arial;
}

The fix was to match font metrics:

body {
  font-family: 'CustomFont', Arial;
  font-size: 16px;
  line-height: 1.5;
}

/* Ensure fallback font matches */
@supports not (font-family: 'CustomFont') {
  body {
    font-size: 15.5px;
    letter-spacing: 0.2px;
  }
}

Another pitfall was Service Worker caching. Misconfiguration meant users never saw updates:

// Wrong caching strategy
self.addEventListener('fetch', event => {
  event.respondWith(caches.match(event.request));
});

// Correct approach: Network-first, fallback to cache
self.addEventListener('fetch', event => {
  event.respondWith(
    fetch(event.request)
      .catch(() => caches.match(event.request))
  );
});

本站部分内容来自互联网,一切版权均归源网站或源作者所有。

如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn

Front End Chuan

Front End Chuan, Chen Chuan's Code Teahouse 🍵, specializing in exorcising all kinds of stubborn bugs 💻. Daily serving baldness-warning-level development insights 🛠️, with a bonus of one-liners that'll make you laugh for ten years 🐟. Occasionally drops pixel-perfect romance brewed in a coffee cup ☕.