Chinese Web Fonts Are Why Your Site Loads Slowly
8 min read
You open a site and the layout sits blank for three seconds, five seconds, and then all the text appears at once. Sites in Chinese, Japanese or Korean hit this far more often than sites in Latin scripts, and the cause is usually the fonts. One CJK font file can outweigh every other resource on the page combined, and fonts happen to be the kind of resource that holds text back from being drawn. That is what the visitor is watching during those blank seconds. This covers how to tell whether fonts are your problem, which four places to change, and what each change costs you in the long run.
1. Why CJK fonts are so much heavier
The gap is a matter of how the writing systems work. A Latin font weight covers an alphabet, digits, punctuation and accented forms, which comes to roughly 200 to 400 glyphs, around 20 to 40 KB once compressed to woff2. Chinese has no alphabet: every word is written with characters that each need their own drawn glyph, and everyday use already runs to five or six thousand of them, with a full set past twenty thousand. Japanese adds two kana syllabaries on top of several thousand kanji, and Korean fonts normally ship over eleven thousand precomposed hangul syllables. Compressed the same way, one CJK weight lands somewhere between 3 and 8 MB. That is a hundredfold difference, not a slight increase.
The weight then stacks up further. Variable fonts pack several weights into one file, which is convenient and also bigger. Sites in Chinese also tend to use one family for headings and another for body text, so two large files load at once. Put two CJK families on a site and the fonts alone can outweigh everything else you serve.
Fonts differ from images in one way that matters. An image that has not finished loading does not stop the text beside it from being read. A font that has not finished loading leaves its text either missing or drawn in a system face that swaps out later. Those are the blank seconds the visitor sits through, and measurement tools report them directly as poor first contentful paint and largest contentful paint figures.
When Google's font service delivers Chinese it splits the family into hundreds of small slices. That sounds like it spreads the load, but the more varied the characters on your page, the more slices actually get downloaded, and the total does not shrink. Mobile networks and older handsets take the worst of it, while a desktop on a fixed line hides the problem entirely, which is why anyone testing on desktop alone concludes everything is fine.
2. Confirming that fonts are the cause
The quickest route is to put the URL into Google PageSpeed Insights and see whether fonts appear among the items it blames for the load time. For a closer look, press F12 in the browser, open the network tab and reload, then check how large each font file is and how long it took.
Write down these four while you measure
- The scores and seconds before you change anything. Record one PageSpeed Insights run as your baseline, or you will have nothing to compare against.
- Total font transfer, and the slowest single file. Disable cache in the network tab, reload, then filter to font files.
- Whether fonts come from an outside service. Addresses containing fonts.googleapis.com or fonts.gstatic.com are the tell. Every extra outside host adds another connection to set up before anything downloads.
- The numbers under mobile conditions. Turn on network throttling and CPU slowdown in the browser and measure again, so the figures resemble a real visitor's.
The giveaway is timing. If the moment text appears on screen lines up with the moment the last font file finished downloading, you have your culprit. Then look at which element on the page is the largest piece of content. If it is a line of heading text, the case against the fonts gets stronger.
3. Four fixes, easiest first
These four work in order. The first two pay off the same day; the last two take some work. With all four done, a site that was loading several CJK families can realistically get total font weight under 200 KB.
| Fix | What it saves | What it costs |
|---|---|---|
| Drop font families | Every CJK family removed is several MB not downloaded | Slightly less variety in the design |
| System fonts for body text | CJK body text downloads nothing at all, typically 200 KB and up saved | Body text looks slightly different across devices |
| Self-host the fonts | No wait on an outside service, and you decide how long browsers keep the file | Check the licence allows self-hosting first |
| Keep only the characters you use | A CJK serif used only for headings commonly ends up around 100 KB | You need a process that regenerates it, or new articles will show missing characters |
The order is deliberate. The first two remove things you do not need: count how many families the site actually loads, then delete the decorative ones that appear in a block or two. That alone usually solves most of it. The last two are about handling the family you kept properly, and they take more effort. Measure again after each step, so you know which one earned its keep.
Using system fonts for body text means naming the Chinese faces already installed on the reader's device, so the browser downloads nothing. A common stack for Traditional Chinese is -apple-system, PingFang TC, Microsoft JhengHei, Noto Sans TC, with sans-serif at the end as a backstop. For Simplified Chinese the equivalents are PingFang SC, Microsoft YaHei and Noto Sans SC.
4. Keeping only the characters you use, and what it costs
The tooling side holds no mystery. There are ready-made programs that scan which characters the site actually uses, produce a cut-down font file and write it out as woff2, which compresses better. It runs in seconds. If the font has adjustable weight, narrowing the weight range to what you really use brings the size down further.
A line mixing the subset font with the system font reads as slightly wrong without the reader being able to say which character is at fault. Before committing to this step, be sure you can keep the regeneration going. If you cannot, the layout will quietly degrade over a few months.
The way to control that risk is to make regeneration automatic. Hook the subsetting into the build process or the publishing process so new content triggers a run before it goes live, and missing characters never accumulate. Take the character list from the compiled page content rather than maintaining a list by hand, which is far more reliable.
If automation is out of reach, at least include a standard list of common characters in the heading font's subset as a buffer, at the cost of a somewhat larger file. Keep the original full font file and the steps used to produce the subset, so whoever takes over can rebuild it. And before each release, look over the headings and the navigation with real article content in place. Missing characters are usually obvious to the eye.
5. What to show during the seconds before the font arrives
font-display decides how the browser treats text while the font is still downloading. With swap, the text is drawn in a system face immediately and replaced when the font arrives, so nothing disappears, at the cost of a layout jump at the moment of the swap. With optional, the browser gives up on the font for that visit if it does not arrive quickly, which keeps the layout completely stable, at the cost of some visitors seeing a system face on their first visit.
For most sites, swap on body text is the right call, because at least no paragraph goes blank. Consider optional only if removing the layout jump matters more than everyone seeing the typeface you chose. If that shift really bothers you, tune the fallback font's metrics with size-adjust and ascent-override so its character widths and line height sit close to the real font, and the movement at swap time becomes hard to notice.
6. What self-hosting fixes on the side
Beyond speed, bringing fonts in-house sorts out two other things. Security settings get simpler: a site can restrict which outside hosts it is allowed to request anything from, and two fewer sources means a shorter list to maintain. And there is privacy: you no longer have to tell visitors their connection details go to Google's font service. After the German court ruling on Google Fonts in 2022, which held that embedding them sent visitors' IP addresses to Google without consent, sites with EU visitors tend to care about that point.
Two things to set up once you have self-hosted. Give the font files a long cache lifetime and put a version number in the filename, so a redesign only needs a new filename and returning visitors do not download anything again. And check the licence first: Noto and the Source Han families use the SIL Open Font License, which permits both self-hosting and subsetting, while commercial fonts need reading contract by contract.
7. If it is not the fonts, what else it could be
If the score is still poor once fonts are handled, look at two more places. First, images: uncompressed JPEGs and photos uploaded straight off a phone are frequently the largest element on the page in their own right. Second, the page code: when too much runs at once, the page can be drawn and still not respond to a tap, which the visitor reads as the site being stuck.
Four common causes other than fonts
- Images that were never processed. Convert to WebP or AVIF, export at the size the layout actually uses, and set width and height so the page does not shift while loading.
- The first-screen image set to load lazily. Deferring images below the fold is correct. Deferring the one at the top is not, because it is usually the element that decides when the page looks ready.
- Too much code loading at once. Whole-package imports, carousels and animation libraries: split what can be split, defer what can be deferred.
- WordPress plugins and themes. Start with the plugin count and whatever the theme loads by itself. Plenty of sites feel faster after disabling two or three plugins nobody uses.
Working through those is usually enough. Most loading problems on CJK sites stop at fonts and images, well before anything as drastic as changing host.
Fonts are one of the few changes that touch very little and still move the numbers. A site that was pulling several CJK families from a third party can, after those four steps, see the moment text first appears drop from well over ten seconds to under two, with nothing changed but how fonts load. The layout and the content stay exactly as they were. These figures do vary between test environments, so measure before and after under the same conditions and trust the trend rather than any single run.
Common questions
- Does loading Chinese fonts from Google Fonts slow a site down?
- Yes, and the gap is far wider for CJK than for Latin. The font files are large to begin with, and you also connect to two extra hosts to fetch them, which hurts most on mobile networks. On sites loading several Chinese families, taking more than ten seconds for text to appear is not unusual. Self-hosting and cutting the file to the characters actually in use typically brings that near two seconds. If your site uses a single Latin family, the effect is much smaller and there is no urgency.
- After subsetting a Chinese font, what happens when a new article uses a character that was left out?
- That one character falls back to the system font. On its own you might not notice, but in a heading beside the subset font the mismatch in weight and stroke style is visible. The fix is to hook regeneration into your publishing or build process, or to include a list of common characters in the subset as a buffer, which makes the file larger. Without a maintenance process, stick to the first two steps: fewer families, and system fonts for body text.
- If body text uses a system font stack, will it look very different across devices?
- There will be differences. macOS and iOS render in PingFang, Windows in Microsoft JhengHei or a locally installed Noto Sans TC, Android in Source Han Sans, and character widths and line heights are not identical. At body text size most readers never notice, and in exchange the CJK download drops to zero. If the brand has strict requirements for body type, keep a self-hosted font and accept the weight that comes with it.