I pulled up Lighthouse on my phone for arcs.health and the numbers were bad enough that I refreshed twice, hoping for a fluke. They weren’t flukes. Then I checked covenant.clinic and got the same sinking feeling — not broken, just the kind of mediocre that quietly costs you patients who bounce before the page finishes loading. Both sites hit 100/100/100/100 on mobile Lighthouse within a few focused sessions, but the thing that got us there wasn’t what I reached for first.
The biggest win was deleting code. arcs.health was shipping an entire SPA framework — a single-page app, the kind where JavaScript builds every page in the browser — to homepage visitors who only needed a headline and a button. Every visitor paid for route code they never used. covenant.clinic was midway through leaving Webflow and still carried runtime remnants on every page load.
And both had robots.txt files that Lighthouse flagged as invalid, even though the source files in our repo were pristine.

Where they started
Two sites, different symptoms, same root cause: architectural overhead we’d stopped noticing.
| Site | Key Problems |
|---|---|
| arcs.health | Full SPA bundle on static homepage, oversized images, invalid robots.txt |
| covenant.clinic | Webflow runtime remnants, render-blocking CSS, CLS from hero images, stale CDN cache |
I nearly started by shaving a few kilobytes and deferring a script. That was the wrong order.
Fix Architecture First, Optimize Second
The arcs.health homepage is a static marketing page. It doesn’t need a framework. But because the rest of the app used one, the homepage downloaded the entire bundle — router, state management, component tree — for every visitor who might never click past /.
The fix was a lightweight static HTML shell that only loads the SPA when someone navigates deeper. A few lines of inline JavaScript at the bottom of <body> check the path and inject the framework only when it’s actually needed:
the mechanism — lazy loading, critical CSS, and edge debugging give me the detail
Lazy SPA hydration — the homepage becomes a plain HTML+CSS shell; the framework bundle is injected only when the path differs from /. This works because browsers execute inline <script> synchronously during parse, so the branch runs before any network request is made for the bundle. No framework needed:
<script>
if (window.location.pathname !== '/') {
const link = document.createElement('link');
link.rel = 'stylesheet';
link.href = '/assets/index.css';
document.head.appendChild(link);
const script = document.createElement('script');
script.type = 'module';
script.src = '/assets/index.js';
document.body.appendChild(script);
}
</script>Critical CSS inlining — to fix CLS after the non-blocking CSS experiment, above-the-fold rules are inlined in <style> at response time (a short build step using critical or a custom Bun/Node extractor). The full stylesheet still loads async; the inline block prevents the unstyled flash that causes layout shift.
Edge debugging — to catch what Cloudflare Bot Management was injecting into robots.txt, use curl -I plus a raw body fetch on the public URL, not localhost:
curl -s https://your-domain.com/robots.txt | head -20Compare that output against your source file. Any directive you didn’t write came from the edge. Cloudflare’s Managed Robots feature (under Bot Management settings) is the usual culprit; disabling it via the API restores origin control while leaving AI-bot rules intact.
Image variants — responsive <source> sets (WebP + AVIF with JPG/PNG fallbacks) were generated with sharp in a one-time build script. The key is matching sizes to your actual rendered breakpoints, not defaulting to 100vw.
For covenant.clinic, the architecture fix meant leaving Webflow’s hosting entirely. We stood up a dedicated Bun service — Bun is a JavaScript runtime, like Node but faster — took ownership of every response header, and built an explicit redirect map for legacy booking paths. The mystery middleware between us and the browser was gone.
Deleting the unnecessary SPA bundle from the homepage did more than all the image compression, script deferral, and cache tweaks combined. The structural problem came first; the fine-grained knobs waited until the thing that should not have been there was gone.
The CSS trap: faster FCP, worse page
This was my wrong turn.
On covenant.clinic, I tried a textbook optimization: converting the main stylesheet from a blocking <link> tag to a non-blocking preload pattern. The idea is straightforward — let the page paint before CSS arrives so the browser has something to show immediately.
FCP improved. FCP is First Contentful Paint, the moment anything first appears on screen. The number went up, and I thought I had fixed it.
Then CLS spiked. CLS is Cumulative Layout Shift — how much the page jumps around while loading. On visually dense marketing pages, content paints before styles arrive. The user sees a flash of unstyled text and images, then everything snaps into place as CSS loads. Lighthouse FCP looks better. The actual experience is worse. Nobody wants to watch a page rearrange itself.
The fix was to inline the critical CSS — the styles needed for what is visible above the fold — in a <style> tag at response time. That kept the page stable and removed the extra stylesheet round-trip. CLS dropped to near-zero and we kept the FCP gains.
A faster paint that moves the page around is worse than a slightly slower stable paint. That wrong turn also made the role of metrics clear to me: they measure things that serve users; they are not the goal themselves. A good number does not matter when the page still feels wrong. I check CLS traces after changing CSS loading, not just the speed numbers.
The Robots.txt Mystery
Both sites had the same bizarre issue. I opened the robots.txt in the repo, verified it was valid, ran Lighthouse, and watched it fail. I repeated that three times before checking what the public URL served.
The culprit was Cloudflare’s Bot Management feature — a setting that sits between our origin server and visitors, blocking bad bots. It was silently injecting a Content-Signal directive into the served robots.txt. That’s a non-standard directive Lighthouse doesn’t recognize, so it rejects the whole file. This happened at the edge — at Cloudflare’s servers — even though our origin files were correct.
The fix required Cloudflare’s global-key API to disable managed robots injection while keeping AI bot blocking active. Once the origin controlled robots again, both sites passed clean.
I now validate the public response. A CDN — content delivery network, the edge servers between your origin and visitors — can change a response without changing the source file. I curl the production URL because localhost is not enough. One curl against the production URL would have saved me an hour of staring at a valid source file while Lighthouse disagreed.
Cache purge is part of deployment. After a change that touches content paths, I purge the affected URLs from the CDN cache. Otherwise Lighthouse measures yesterday’s site against today’s expectations.
Image Optimization: Context-Aware, Not Blanket
For both sites, we generated responsive image variants sized to the actual rendered dimensions. This was not a blanket “make everything smaller” pass:
| Asset | Before | After |
|---|---|---|
| arcs.health hero | 1 large JPG, all devices | 700w + 1000w WebP with JPG fallback |
| arcs.health logo | 1 large PNG | 300w + 600w WebP with PNG fallback |
| covenant.clinic hero | Unsized, single source | Explicit dimensions + 470w AVIF variant |
Every image got explicit width and height attributes. This is the cheapest win in the entire playbook — it takes seconds per image and eliminates layout shift warnings entirely by telling the browser how much space to reserve before the image loads.
The final scores
Together, these specific changes moved two real healthcare websites from “fine” — the word I used when I did not want to look too closely — to perfect scores. The same playbook is reusable for any content-heavy site sitting behind a CDN.
| Metric | arcs.health | covenant.clinic |
|---|---|---|
| Performance | 100 | 100 |
| Accessibility | 100 | 100 |
| Best Practices | 100 | 96 |
| SEO | 100 | 100 |
| FCP | 0.8s | 0.8s |
| LCP | 0.9s | 1.8s |
| CLS | 0 | 0.011 |
covenant.clinic’s Best Practices deduction comes from third-party scripts (GTM, Clarity) — not something we control in first-party rendering. Accessibility is cheap. Adding aria-label attributes, <main> landmarks, and descriptive link text took minutes and moved Accessibility from the mid-90s to 100. No redesign was required.