DEV Community

Tan Phan
Tan Phan

Posted on

How I Fixed a 42/100 Lighthouse Score on a B2B 3D WebGL Landing Page (and Open-Sourced the Fix)

A few weeks ago, I was building a B2B landing page that embedded an industrial 3D model using <model-viewer>. The page looked fantastic. Then I ran Lighthouse.

Score: 42/100.

Here are the silent killers I found - and what made them non-obvious:

1. The Font Weight Trap (8 requests instead of 3)

Google Fonts was loading wght@300;400;500;600;700;800. That's 6 weights for Inter plus 2 for JetBrains Mono = 8 separate HTTP requests just for fonts.
Each one is render-blocking.
The fix: Reduce to exactly the weights used (400;600;700). Saved ~400ms.

2. <model-viewer> Blocking the Main Thread

The WebGL script was 300KB. Sitting right in the <head>.
The fix: Move it to the very end of the <body>. Use type="module" so the browser defers it automatically.

3. The Silent SEO Killer: JavaScript in JSON-LD

This was the nastiest bug.
A background animation (Particle.js) was running on the page. Due to a weird timing issue, it injected callback code directly into my <script type="application/ld+json"> block.
The page looked perfect visually. No console errors. But the JSON-LD was now invalid. Google Search Console quietly dropped my rich snippets for 3 months before I noticed.


The Open-Source Fix: web-performance-surgeon

I got tired of hunting these issues manually, so I built a Python CLI that scans your HTML and auto-fixes all of them in one go:

# Audit only - shows all issues
python web_performance_surgeon.py index.html

# Audit + auto-fix everything
python web_performance_surgeon.py index.html --fix
Enter fullscreen mode Exit fullscreen mode

Final score after fixes: 100/100 Lighthouse.

I've open-sourced this tool along with my entire B2B web toolchain (including a JSON-LD guardian that specifically catches the injection bug):
GitHub: tanphan1105/web-performance-surgeon

Has anyone else run into that JSON-LD corruption bug? It's terrifying how silently it fails.

Top comments (0)