Render-blocking CSS, Cloudflare HTML rewrite, fixed hero heights, and Watcher domain report Summary before and after
Our corporate site at apogee.lu is a static marketing front door: two HTML pages, a hero photograph, Victor Mono typography, and no application server in the path. It should be an easy Core Web Vitals win. Earlier this month, PageSpeed Insights on mobile still reported First Contentful Paint and Largest Contentful Paint above 2.5 seconds, with render-blocking CSS and a filmstrip that stayed blank until late in the load. We build Apogee Watcher to monitor PageSpeed for client estates; tuning our own homepage was overdue, and we used the new domain-level report Summary to keep the work honest across every URL we ship under that host.
Below is the sequence we ran: domain triage, diagnosis, failed experiments, and what landed us at 95 mobile and 100 desktop in lab tests, with Cumulative Layout Shift at 0.
What PageSpeed Insights showed before we changed anything
Mobile lab runs told a consistent story. First Contentful Paint and Largest Contentful Paint were nearly equal, often around 2.6 to 3.0 seconds. The filmstrip showed no painted pixels for most of the timeline, then the full hero appeared in one step. Total Blocking Time stayed at zero; the bottleneck was not JavaScript on the main thread. Lighthouse flagged render-blocking index.css from our asset CDN. Speed Index lagged because the visible hero arrived only after CSS allowed layout.
That single-URL picture was useful, but incomplete. apogee.lu also ships mailops.html and will keep growing small product pages. A green homepage with a neglected second URL is how agencies ship “we fixed PageSpeed” stories that fall apart on the next client call.
How we used Watcher domain reports before touching CSS
Before we edited templates, we generated a domain report for the host and opened it on the Summary tab. Shared domain reports now default to Summary: an attention-free score (the share of completed mobile and desktop tests that pass Performance, category, and Core Web Vitals gates), a short list of metrics that still need attention, and the top pages that fail those gates. For apogee.lu that view made three decisions cheap: the homepage on mobile was the first attention sink (LCP and render-blocking CSS), not a desktop-only quirk; mailops.html either shared the same head and hero pattern or needed its own pass; and a shareable #summary link kept the before state visible while we experimented locally. Single-URL PageSpeed Insights remains the right drill-down once Summary names the URL and strategy. Domain Summary is what stops you from optimising the wrong page first.
How we found the real Largest Contentful Paint bottleneck
Lighthouse named the hero photograph as the Largest Contentful Paint element, but the image was not the first gate. Our 500w WebP hero is about 15 KB and often finished downloading before layout. The gate was synchronous CSS: the browser waited for stylesheet parse before painting.
On production we also found Cloudflare injecting a cdn-cgi/challenge-platform script into HTML. That script added main-thread work and pushed Largest Contentful Paint above 2.9 seconds. Setting Cache-Control: no-transform on HTML from Apache stopped rewrite; injected scripts left view-source and lab Largest Contentful Paint dropped by roughly a second.
Moving assets to our CDN and reordering the document head
We moved images, CSS, JavaScript, and fonts to https://cdn.apogee.lu/assets/ with preconnect in the head. Critical links now run before title and social meta so discovery order matches what lab filmstrips punish: CDN first, then paint-critical assets, then the rest of the document chrome.
preconnect to the CDN
- Hero image
preload (500w on mobile via <picture>)
- Font preloads and
victor-mono.css
- Main CSS
preload and synchronous stylesheet
The hero download starts in the head even though paint still waits on CSS. That parallel fetch is why preload still helps Largest Contentful Paint when the stylesheet remains synchronous.
Hero images and fixed heights per breakpoint
We ship WebP at 500w, 780w, 1200w, and full width. <picture> serves 500w on viewports up to 980px so mobile does not pull a 780w file on a 2x screen. The preload uses media="(max-width: 980px)" so lab mobile requests the smaller asset first.
Fluid height caused Cumulative Layout Shift when we tried async CSS. min-height: clamp(420px, 62vh, 720px) gave 577px on an iPhone 15 Pro Max (62% of 932px viewport height). Late full CSS shifted .hero-stage and Lighthouse scored 0.197 Cumulative Layout Shift.
We replaced fluid height with fixed values from the same formula at canonical breakpoints:
| Breakpoint | Reference viewport | Fixed height |
| ≤980px | 390×844 | 524px |
| 981-1360px | 1280×900 | 558px |
| ≥1361px | design cap | 720px |
Mobile lab Cumulative Layout Shift returned to 0 after deploy. That is the same “reserve space” idea you see in CLS how-tos, applied to a hero stage whose height was CSS-driven rather than an <img> without dimensions. Width and height on the image alone would not have stopped the stage from resizing when late CSS replaced the fluid min-height.
CSS and fonts: what we tried and what we kept
Extracting inline CSS into index.css shrank HTML but did not remove render-blocking.
Inline critical CSS plus async full stylesheet cut First Contentful Paint to about 1.0 seconds locally and cleared the render-blocking warning. It also broke typography (font-display: optional skipped Victor Mono on slow links) and pushed Cumulative Layout Shift back up when below-the-fold rules arrived late. We kept synchronous main CSS and self-hosted Victor Mono on the CDN instead: four latin WOFF2 files and a small @font-face sheet, with preloads for normal and italic latin, and font-display: swap so the correct family appears after files load. The Lighthouse render-blocking warning can remain while Performance still lands in the mid-90s; we preferred stable layout and brand fonts over chasing a green Opportunities row.
Scores after deploy and what Summary showed next

Mobile PageSpeed Insights after CDN alignment (captured 30 Aug 2026):
- Performance 95
- First Contentful Paint ~1.7s, Largest Contentful Paint ~2.4s
- Cumulative Layout Shift 0, Total Blocking Time 0ms
Desktop lab reached 100 with sub-second paint metrics (FCP 0.5s, LCP 0.6s, Speed Index 0.7s). Speed Index on mobile can stay above 4 seconds because the hero image paints after text; we accept that on a rarely changed marketing page rather than reopening the async-CSS experiment.
We regenerated the domain report and opened Summary again. All 4 completed page tests passed the CWV and category gates, so the attention-free score sat at 100%, with average Lighthouse Performance 97 on mobile and 100 on desktop.

That before/after pair is what we keep when someone asks whether the ship actually moved the portfolio, not only one PageSpeed Insights screenshot.
What we monitor now
We keep apogee.lu on scheduled PageSpeed runs in Watcher and re-check after HTML header, Cloudflare, or CDN cache changes. Lab green after deploy proves the fix shipped. Search Console field data still moves on its 28-day CrUX window, so we do not treat one green lab week as field proof.
Manual PageSpeed Insights before every deploy does not scale across client sites. Apogee Watcher automates runs, stores history, and alerts on regression. Domain reports with Summary give you the same triage shape we used on our own host. For pipeline versus scheduled monitoring, see Lighthouse CI vs managed monitoring.
FAQ
Does CDN CSS stop render-blocking?
No. Synchronous stylesheet blocks first paint until parsed, even for a small file. Preload helps discovery; async or inlined critical CSS removes the gate. We used sync CSS plus fixed hero height to hold Cumulative Layout Shift at zero.
Why preload the hero if CSS blocks paint?
The image can download in parallel with the stylesheet. When paint is allowed, Largest Contentful Paint is shorter if those bytes are already cached instead of starting only after CSS finishes.
Why open a domain report instead of only PageSpeed Insights?
PageSpeed Insights answers one URL. Domain Summary answers which URLs and strategies still need attention under one host, with an attention-free pass rate you can share. Drill into Opportunities after Summary names the page.
Next step: Run PageSpeed Insights on your homepage. If First Contentful Paint equals Largest Contentful Paint in the filmstrip, check render-blocking CSS and injected scripts before resizing images. Generate a free domain scan, open #summary, then start a Watcher trial to keep the same URLs on a schedule.
References
Originally published on Hashnode.