perf: the word lists travel as .txt, which the host compresses

GitHub Pages serves a .dic as text/x-c and leaves it uncompressed, while
text/plain goes out gzipped: the English list cost 552 KB over the wire
where 191 KB would do. Only the fetch path changes; the mount name the
checker sees stays <code>.dic. Measured first load 1.83 → 1.70 MB.
This commit is contained in:
Steffen Becker committed 2026-09-06 19:07:11 +02:00
1 parent 6b6b621a5a
commit f6c906f9fa
4 files changed
+5 -4

No files matched your search

File renamed without changes.
File renamed without changes.
+4 -3
View File
@@ -29,13 +29,14 @@ async function fetchBytes(url: string): Promise<Uint8Array> {
}
async function build(code: string): Promise<Checker> {
// Vendored assets: public/dictionaries/<code>/<code>.{aff,dic}. BASE_URL keeps
// this correct under a non-root deploy base.
// Vendored assets: public/dictionaries/<code>/<code>.{aff,dic.txt}. The word list is
// .txt so the host gzips it (GitHub Pages leaves a .dic's text/x-c uncompressed);
// BASE_URL keeps the path correct under a non-root deploy base.
const base = `${import.meta.env.BASE_URL}dictionaries/${code}/${code}`;
const [factory, aff, dic] = await Promise.all([
loadFactory(),
fetchBytes(`${base}.aff`),
fetchBytes(`${base}.dic`),
fetchBytes(`${base}.dic.txt`),
]);
const affPath = factory.mountBuffer(aff, `${code}.aff`);
const dicPath = factory.mountBuffer(dic, `${code}.dic`);
+1 -1
View File
@@ -14,7 +14,7 @@ function dictPath(rel: string): string {
async function makeChecker(code: string): Promise<Hunspell> {
const factory = await loadModule();
const aff = factory.mountBuffer(readFileSync(dictPath(`${code}/${code}.aff`)), `${code}.aff`);
const dic = factory.mountBuffer(readFileSync(dictPath(`${code}/${code}.dic`)), `${code}.dic`);
const dic = factory.mountBuffer(readFileSync(dictPath(`${code}/${code}.dic.txt`)), `${code}.dic`);
return factory.create(aff, dic);
}