perf: move the 19 non-zh/en dictionaries into a lazy locale chunk

The core client bundle statically imported every third-language
dictionary (ja/de/fr/…/zh-HK/MO/TW, ~640KB of source — roughly half
the bundle's weight) for a code path most sessions never enter: the
sidebar's own t() only consults zh/en plus the better-locale override
store, and the dicts' ONLY consumer is that store's register() call.

They now ride the existing lazy-chunk machinery as lib/client-locale.js
(fetched from /sidebar/bundle only when better-locale is actually
installed; a generation counter keeps the async registration moot when
the integration effect re-runs or disposes mid-flight). Until the chunk
lands, t() keeps the zh/en chain; the store's own revision bump on
register re-renders the chrome once the dicts arrive.

Core client.js: 1.46MB → 822KB (-44%). The chunk-boundary key-set
check moves to the existing runtime test (every shipped dict stays
key-set-equal to zh).
This commit is contained in:
Menghuan1918
2026-09-01 16:01:34 +08:00
parent b7af498427
commit c7d58c9b25
8 changed files with 100 additions and 69 deletions
+1 -1
View File
@@ -145,6 +145,6 @@ describe('/sidebar/bundle route', () => {
})
it('exports the chunk allowlist (mirror of src/client/chunk-loader.ts)', () => {
expect([...CHUNK_NAMES]).toEqual(['terminal', 'editor', 'mermaid'])
expect([...CHUNK_NAMES]).toEqual(['terminal', 'editor', 'mermaid', 'locale'])
})
})
+10 -14
View File
@@ -6,7 +6,8 @@
* interpolation.
*/
import { afterEach, describe, expect, it } from 'vitest'
import { LOCALE_NS, attachBetterLocale, attachLocale, en, isZh, ja, relativeTime, t, zh, de, fr, pt, ko, ar, hi, id as idDict, tr, vi, th, ru, it as itDict, nl, sv, pl, zhHK, zhTW, zhMO } from '../src/client/locales.ts'
import { LOCALE_NS, attachBetterLocale, attachLocale, en, isZh, relativeTime, t, zh } from '../src/client/locales.ts'
import { localeDicts } from '../src/client/chunks/locale.tsx'
/** Minimal structural fake of the DSH LocaleService face the sidebar uses. */
class FakeLocale {
@@ -108,20 +109,15 @@ describe('locales (DSH i18n following)', () => {
expect(Object.keys(en).sort()).toEqual(Object.keys(zh).sort())
})
it('keeps the ja dictionary key-set-equal to zh', () => {
expect(Object.keys(ja).sort()).toEqual(Object.keys(zh).sort())
})
it('keeps every shipped third-language dictionary key-set-equal to zh', () => {
// The third-language dicts are typed `Record<keyof typeof zh, string>` via
// an `as` cast (unchecked by tsc). This test catches missing/extra keys
// introduced when a zh key is added without updating every language.
const thirdLangs = {
de, fr, pt, ko, ar, hi, idDict, tr, vi, th, ru, itDict, nl, sv, pl, zhHK, zhTW, zhMO,
}
for (const [lang, dict] of Object.entries(thirdLangs)) {
expect(Object.keys(dict as Record<string, string>).sort(), lang).toEqual(Object.keys(zh).sort())
// The third-language dicts live in the lazy locale chunk typed as plain
// records (the chunk boundary has no key-set type tie to zh). This test
// catches missing/extra keys introduced when a zh key is added without
// updating every language — a missing key silently falls back to en.
for (const [lang, dict] of Object.entries(localeDicts)) {
expect(Object.keys(dict).sort(), lang).toEqual(Object.keys(zh).sort())
}
expect(Object.keys(localeDicts), 'every shipped third language rides the locale chunk').toContain('ja')
})
})
@@ -247,7 +243,7 @@ describe('locales (better-locale override)', () => {
locale.switchTo('en')
attachLocale(locale)
const betterLocale = new FakeBetterLocale({ [LOCALE_NS]: { ja } })
const betterLocale = new FakeBetterLocale({ [LOCALE_NS]: { ja: localeDicts.ja! } })
betterLocale.active = 'ja'
attachBetterLocale(betterLocale)