◉ANTIGRAVITY LABJP
Articles/Tips & Best Practices
✦ Tips & Best Practices/2026-10-27Advanced

Dropping a Japanese Web Font Cut FCP from 4.1s to 1.7s; Half My Explanation Failed a Minimal Repro

Mobile FCP on PageSpeed fell from 4.1s to 1.7s once I stopped serving a Japanese web font. Self-hosting made it worse, and the render-blocking story did not reproduce.

web fontsFCPPageSpeednext/fontperformance14

✦ Premium Article

When I opened the mobile result in PageSpeed Insights, the article page showed an FCP of 4.1 seconds. The top page showed an FCP of 7.7 seconds and an LCP of 9.5 seconds.

I suspected images first. I work with wallpaper images every day, so heavy files feel like familiar territory, and I assumed the LCP element would be one of them. It was text. What was slow was the font that draws that text.

The short version: once I stopped serving a Japanese web font, the numbers moved a lot. But my explanation of why they moved is only half confirmed.

Below I keep three things apart: the change that worked, the change that backfired, and the explanation I could not reproduce.

The numbers pointed at text, not images

The sites I run as Dolice loaded Noto Sans JP from Google Fonts for body text, in four weights: 300, 400, 500, and 700.

PageFCPLCP
Article page (before)4.1 s—
Top page (before)7.7 s9.5 s

PSI's mobile profile assumes a slow CPU and a slow connection. It is harsher than a real phone, which is exactly why it shows what the first paint is waiting for.

Once the LCP element turned out to be text, my search moved from image optimization to font delivery.

A 121KB stylesheet with 496 @font-face rules

I fetched the Google Fonts CSS with a Chrome user agent and measured it. The CSS differs per browser, so always send a realistic UA.

UA="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36"
URL="https://fonts.googleapis.com/css2?family=Noto+Sans+JP:wght@300;400;500;700"
 
# Transfer size (gzip)
curl -s -A "$UA" -H "Accept-Encoding: gzip" -o /dev/null -w "gzip transfer=%{size_download}B\n" "$URL"
# Expanded size and the number of @font-face rules
curl -s -A "$UA" -H "Accept-Encoding: identity" "$URL" | tee /tmp/css2.txt | wc -c
grep -c "@font-face" /tmp/css2.txt

I re-ran this on the day I wrote this article:

ItemValue
Transfer size (gzip)121,308 bytes (about 121KB)
Expanded size447,832 bytes (about 448KB)
@font-face rules496 (4 weights × 124 subsets)

A Japanese font has too many glyphs for one file, so Google Fonts splits it with unicode-range. The browser only downloads the woff2 files that contain the characters on the page. But to decide which subsets it needs, it must first read all 496 declarations.

If you carry over the intuition from Latin fonts, where the CSS is a few kilobytes, your estimate misses by a wide margin.

✦

Thank you for reading this far.

Continue Reading

What follows includes implementation code, benchmarks, and practical content we hope you'll find useful. This site runs without ads — server and development costs are supported entirely by members like you. If it's been helpful, we'd be truly grateful for your support.

WHAT YOU'LL LEARN
✦You can now check an external font stylesheet's transfer size and @font-face count before blaming images when mobile FCP is slow
✦You can now compare compressed size and FCP side by side, so a self-hosting change does not quietly make things worse
✦You can now run a few dozen lines of repro code against your own explanation, such as render-blocking, and verify it again after the fix
Secure payment via Stripe · Cancel anytime
✦

Unlock This Article

Get full access to the rest of this article. Buy once, read anytime. This site is ad-free — your support goes directly toward keeping it running.

or
Unlock all articles with Membership →
Share

Thank You for Reading

Antigravity Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • ✦Copy-paste ready implementation code
  • ✦New advanced guides published daily
  • ✦$5/mo or $10 for lifetime access
View Membership →

Related Articles

✦ Tips2026-03-30
Fixing a Slow or Freezing Antigravity: Find the Cause Before You Change Anything
When Antigravity's agent is slow or the UI freezes, narrow down the cause before touching settings: context size, MCP servers, model and mode, truncated output, and Auto-continue.
✦ Tips2026-10-27
A 60-Line PreToolUse Hook That Stops an Agent's rm -rf Before It Runs
How to block rm -rf and git push --force before they execute, using an Antigravity CLI PreToolUse hook. Includes what a one-line grep missed across 16 test commands.
✦ Tips2026-10-25
Which Antigravity Does "antigravity" Launch in WSL2 — Windows or Linux? How to Tell, and Which One to Keep
You installed the Linux build in WSL2, yet things feel slow or a Windows window opens. This walkthrough uses type -a and PATH order to find what actually launches, then helps you decide which build to keep.