Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 11 additions & 0 deletions packages/i18n/bench/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# I18n Benchmarks

These benchmarks must be ran in an actual browser extension environment.

To run them, run `bench/run.ts` and load the `bench/` directory into a browser as an extension. Or just:

```sh
bun --cwd packages/i18n bench
```

Benchmarks are defined in `bench/background.ts`. Add or edit them there.
17 changes: 17 additions & 0 deletions packages/i18n/bench/_locales/en/messages.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"simple": {
"message": "Just plain text"
},
"substitution": {
"message": "Includes one substitution: $1"
},
"singular": {
"message": "There is $1 item"
},
"plural": {
"message": "There are $1 items"
},
"wxtPlural": {
"message": "There is $1 item | There are $1 items"
}
}
85 changes: 85 additions & 0 deletions packages/i18n/bench/background.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import { Bench } from 'tinybench';
import { createI18n } from '../src';

declare const chrome: any;

export const i18n = createI18n();

// Keep service worker alive
setTimeout(() => {
chrome.runtime.getPlatformInfo();
}, 20e3);

(async () => {
const results: Record<string, any> = {};
const runBench = async (bench: Bench) => {
await reportProgress(`[start] ${bench.name}`);
await bench.run();
results[bench.name!] = bench.table();
await reportProgress(`[done] ${bench.name}`);
};

{
const key = 'simple';
const simple = new Bench({ name: 'Simple' })
.add('Vanilla', () => void chrome.i18n.getMessage(key))
.add('WXT I18n', () => void i18n.t(key));
await runBench(simple);
}

{
const key = 'substitution';
const value = 'test';
const substitution = new Bench({ name: 'Substitution' })
.add('Vanilla', () => void chrome.i18n.getMessage(key, [value]))
.add('WXT I18n', () => void i18n.t(key, [value]));
await runBench(substitution);
}

{
const vanillaPluralKey = 'plural';
const wxtKey = 'wxtPlural';
const one = 1;
const pluralSingular = new Bench({
name: 'Plural (singular form)',
})
.add(
'Vanilla',
() => void chrome.i18n.getMessage(vanillaPluralKey, [one]),
)
.add('WXT I18n', () => void i18n.t(wxtKey, one));
await runBench(pluralSingular);

const two = 2;
const vanillaSingularKey = 'singular';
const pluralPlural = new Bench({
name: 'Plural (plural form)',
time: 1000,
})
.add(
'Vanilla',
() => void chrome.i18n.getMessage(vanillaSingularKey, [two]),
)
.add('WXT I18n', () => void i18n.t(wxtKey, two));
await runBench(pluralPlural);
}

// Report results
await reportResults(results);
})();

async function reportProgress(message: string) {
const res = await fetch('http://localhost:3000/progress', {
method: 'POST',
body: message,
});
if (!res.ok) throw Error('Progress report failed...');
}

async function reportResults(results: any) {
const res = await fetch('http://localhost:3000/results', {
method: 'POST',
body: JSON.stringify(results, null, 2),
});
if (!res.ok) throw Error('Results report failed...');
}
11 changes: 11 additions & 0 deletions packages/i18n/bench/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"$schema": "https://json.schemastore.org/chrome-manifest",
"name": "WXT I18n Benchmark",
"version": "1.0.0",
"manifest_version": 3,
"default_locale": "en",
"background": {
"type": "module",
"service_worker": "dist/background.js"
}
}
48 changes: 48 additions & 0 deletions packages/i18n/bench/run.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { join, relative } from 'node:path';

const distDir = join(import.meta.dir, 'dist');
const backgroundSrc = join(import.meta.dir, 'background.ts');

console.log('\nBuilding benchmark extension...');
await Bun.build({
entrypoints: [backgroundSrc],
outdir: distDir,
format: 'esm',
});
console.log('Done!');

console.log(
`\nInstall the extension from ./${relative(process.cwd(), import.meta.dir)} (or reload it) to run benchmarks.`,
);
console.log('Waiting for benchmark results...');

const CORS_HEADERS = {
'Access-Control-Allow-Origin': '*',
};

Bun.serve({
fetch: async (request) => {
// CORS support
if (request.method === 'OPTIONS') {
return new Response(undefined, { headers: CORS_HEADERS });
}

const url = new URL(request.url);
if (url.pathname === '/progress') {
console.log(`\x1b[2m← ${await request.text()}\x1b[0m`);
return new Response(undefined, { status: 202, headers: CORS_HEADERS });
}

if (url.pathname === '/results') {
const body = await request.json();
for (const [name, table] of Object.entries(body)) {
console.log('\n' + name);
console.table(table);
}
setTimeout(() => void process.exit(0));
return new Response(undefined, { status: 202, headers: CORS_HEADERS });
}

return new Response(undefined, { status: 404, headers: CORS_HEADERS });
},
});
2 changes: 2 additions & 0 deletions packages/i18n/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"build": "buildc -- tsdown",
"check": "buildc --deps-only -- check",
"test": "buildc --deps-only -- vitest",
"bench": "buildc --deps-only -- bun run bench/run.ts",
"test:coverage": "bun run test run --coverage",
"prepack": "bun run build"
},
Expand All @@ -46,6 +47,7 @@
"@types/node": "catalog:",
"oxlint": "catalog:",
"publint": "catalog:",
"tinybench": "^6.0.1",
"tsdown": "catalog:",
"typescript": "catalog:",
"vitest": "catalog:",
Expand Down
2 changes: 1 addition & 1 deletion packages/i18n/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"types": ["node"]
"types": ["bun"]
},
"exclude": ["node_modules/**", "dist/**"]
}
Loading