Skip to content

perf(web): inline CSS and lazy-load third-party scripts for mobile LCP - #25

Merged
sarthakagrawal927 merged 1 commit into
mainfrom
perf/lcp-inline-css-lazy-scripts-11
Sep 6, 2026
Merged

sarthakagrawal927 merged 1 commit into
mainfrom
perf/lcp-inline-css-lazy-scripts-11

Conversation

@sarthakagrawal927

Copy link
Copy Markdown
Member

Summary

Mobile LCP p75 was 3.02s after the TTFB fixes in #19/#22/#23 — over the 2.5s CWV gate. TTFB is no longer the bottleneck (186ms); the remaining cost is on the render path.

Two changes, both in the web app:

  1. Inline CSS (build.inlineStylesheets: 'always'). The 37KB stylesheet was served as an external file (Astro's auto threshold is 4KB). On slow 4G that is a full round trip before first paint, and the LCP element is text that cannot render until CSS arrives. Inlining eliminates the round trip — the HTML grows by 37KB but ships in the same response as the content it styles.

  2. Lazy-load third-party scripts. Clarity, sassmaker.com/project-strip.js (23KB), and sassmaker.com/ai-chat-footer.js (48KB) were defer/async but still initiated downloads that stole bandwidth from the CSS on slow 4G. Wrapping all three in requestIdleCallback (1.5s setTimeout fallback) keeps them off the critical path. They still load — just after the page is interactive.

System fonts (Iowan Old Style, Inter) are used throughout, so no web-font loading delay.

Test plan

  • pnpm quality green
  • pnpm --filter @on-record/web build green — no external CSS files in dist
  • psi-swarm mobile LCP p75 < 2500ms after deploy

Refs #11

Generated with Devin

Mobile LCP p75 was 3.02s after the TTFB fixes in #19/#22/#23 — over the
2.5s CWV gate. TTFB is no longer the bottleneck (186ms); the remaining
cost is on the render path:

1. Render-blocking external CSS: a 37KB stylesheet served as an external
   file (Astro's `auto` threshold is 4KB). On slow 4G that is a full
   round trip before first paint, and the LCP element is text that cannot
   render until CSS arrives. Inlining it into a `<style>` tag via
   `build.inlineStylesheets: 'always'` eliminates the round trip — the
   HTML grows by 37KB but ships in the same response as the content it
   styles.

2. Third-party scripts competing for bandwidth: Clarity (~1KB loader),
   `sassmaker.com/project-strip.js` (23KB), and
   `sassmaker.com/ai-chat-footer.js` (48KB) were all `defer`/`async`,
   so they did not block rendering, but they initiated downloads that
   stole bandwidth from the CSS on slow 4G. Wrapping all three in a
   `requestIdleCallback` lazy loader (1.5s `setTimeout` fallback) keeps
   them off the critical path entirely. They still load and function —
   just after the page is interactive.

System fonts (Iowan Old Style, Inter) are used throughout, so there is
no web-font loading delay to address.

Refs #11

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@sarthakagrawal927
sarthakagrawal927 merged commit 9c7cd34 into main Sep 6, 2026
2 checks passed
@sarthakagrawal927
sarthakagrawal927 deleted the perf/lcp-inline-css-lazy-scripts-11 branch September 6, 2026 11:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant