Benchmark
This benchmark compares the transfer size of different i18n libraries and their implementations.
The goal is to understand how the size of the library changes with different configurations, such as the number of locales, messages per page, and namespace size.
If you are looking for a feature comparison, check out the comparison table.
💡 Tip: Paraglide JS has not reached its final optimizations yet. Tickets like #88 per locale builds or #354 pruning server side rendered messages are yet to be implemented. Pull requests are welcome!
What is Being Tested
The benchmark creates a static website for each configuration (library variant, number of locales, messages per page, and namespace size). Each website is loaded in a headless browser, and the total transfer size is measured.
- Number of Locales: How does an i18n library scale with the number of locales?
- Number of used Messages: How does an i18n library scale with the number of messages that are used on a given page?
- Library Implementation Variants: Testing different implementation approaches:
- Paraglide:
default
: Standard implementationexperimental-
: Experimental implementation with per-locale splitting
- i18next:
http-backend
: Using HTTP backend for loading translations
- Paraglide:
- Namespace Size: Testing how the total available messages in a namespace affects bundle size
Library modes
Each library is tested in different modes:
- Paraglide:
- default: Out of the box Paraglide JS with no additional compiler options.
: Mode with a compiler option that is being tested.
- i18next:
Limitations
Choosing the number of messages and namespace varies between projects
Some teams use per component namespacing while other teams have one namespace for their entire project. In cal.com's case, every component that uses i18n loads at least 3000 messages per locale.
To the point of the problem: Avoiding manual chunking of messages into namespaces is the benefit of Paraglide JS. The bundler tree-shakes all unused messages, making namespaces redundant.
Contributing
Contributions to improve the benchmark are welcome.
- adjust the build matrix in
build.config.ts
- run
pnpm run bench
to build the benchmark - run
pnpm run preview
to preview the results