Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cache Intl.* constructors #215

Closed
victorandree opened this issue Mar 15, 2023 · 2 comments · Fixed by #1193
Closed

Cache Intl.* constructors #215

victorandree opened this issue Mar 15, 2023 · 2 comments · Fixed by #1193
Labels
area: performance contributions welcome Good for people looking to contribute enhancement New feature or request

Comments

@victorandree
Copy link

victorandree commented Mar 15, 2023

Is your feature request related to a problem? Please describe.

It seems like on every call to format.number, or similar, there's a call to the corresponding Intl.NumberFormat constructor. This is potentially expensive: A microbenchmark that I constructed suggests a 97% performance decrease (see https://jsbench.me/09lf9t531d/1). An older blog post suggests a more dramatic performance difference: https://blog.david-reess.de/posts/hBEx9w-on-number-formatting-and-performance.

As someone coming from FormatJS, whose documentation emphasizes the use of createIntlCache (see https://formatjs.io/docs/intl), I was a bit surprised to see that this optimization is not present in next-intl.

Admittedly, on modern hardware like my M2 MacBook Pro, the absolute performance seems OK for both cases, even if there's a 49x relative difference.

Describe the solution you'd like

I'd suggest caching the construction of Intl.*Format objects between calls, perhaps by the createFormatter function, or in the context.

Admittedly, this would add complexity and size to the library, for the caching and memoization functionality, and might not be considered worth it.

Describe alternatives you've considered

Alternatively, if this is a known trade-off, I think it'd be good to mention in the documentation that it's been made. For example, in the FAQ section "How is this library different from using react-intl?".

@victorandree victorandree added the enhancement New feature or request label Mar 15, 2023
@amannn
Copy link
Owner

amannn commented Mar 16, 2023

Hi and thanks for the careful analysis!

I ran the performance test that's mentioned in David Reess' blog article and on my 2019 MBP I see that the formatting takes about 0.1ms, so it seems like creating formats have gotten faster (or David used a computer with less CPU power).

That said, if the bundle size is not affected, it would still be interesting to introduce caching.

I'm currently quite busy with the RSC integration and can therefore not look into this at the moment, but if you're affected by this and would be willing to contribute, I'd be happy to review a PR!

The formatting calls are located in this file: https://github.com/amannn/next-intl/blob/be9172099aad1e7057c828065dced5d2c0e0884d/packages/use-intl/src/core/createFormatter.tsx.

We should setup something like CodSpeed to monitor the runtime performance (example).

Note that we should apply caching both to the formats created in useTranslations as well as useFormatter.

@amannn
Copy link
Owner

amannn commented Jun 20, 2024

Just benchmarked this again, and I think we should really cache the constructors:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: performance contributions welcome Good for people looking to contribute enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants