Kanit (th), Noto Sans JP (ja) and Noto Sans KR (ko) were imported statically in main.tsx, so every visitor downloaded ~16MB of CJK font files. They're now loaded on demand once per locale (lib/cjkFonts.ts, wired in LanguageContext), so non-CJK users never fetch them and CJK users get their font after the first paint.
38 lines
1.3 KiB
TypeScript
38 lines
1.3 KiB
TypeScript
import type { Language } from '@/contexts/language';
|
|
|
|
const loaded = new Set<Language>();
|
|
|
|
/**
|
|
* Lazy-load the CJK display font for the active locale.
|
|
*
|
|
* The Thai (Kanit), Japanese (Noto Sans JP) and Korean (Noto Sans KR) font
|
|
* families are large and only needed for users on those locales — but they were
|
|
* imported statically in main.tsx, so every visitor downloaded them. They are
|
|
* now loaded on demand, once per locale, and non-CJK users never fetch them.
|
|
* Text briefly falls back to a system font until the stylesheet resolves.
|
|
*/
|
|
export function loadCjkFont(language: Language): void {
|
|
if (loaded.has(language)) return;
|
|
loaded.add(language);
|
|
|
|
if (language === 'ja') {
|
|
void Promise.all([
|
|
import('@fontsource/noto-sans-jp/400.css'),
|
|
import('@fontsource/noto-sans-jp/500.css'),
|
|
import('@fontsource/noto-sans-jp/700.css'),
|
|
]).catch(() => {});
|
|
} else if (language === 'ko') {
|
|
void Promise.all([
|
|
import('@fontsource/noto-sans-kr/400.css'),
|
|
import('@fontsource/noto-sans-kr/500.css'),
|
|
import('@fontsource/noto-sans-kr/700.css'),
|
|
]).catch(() => {});
|
|
} else if (language === 'th') {
|
|
void Promise.all([
|
|
import('@fontsource/kanit/400.css'),
|
|
import('@fontsource/kanit/500.css'),
|
|
import('@fontsource/kanit/600.css'),
|
|
import('@fontsource/kanit/700.css'),
|
|
]).catch(() => {});
|
|
}
|
|
}
|