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

Add Intl.NumberFormat support, and cache NumberFormat objects when reused #122

Merged
merged 7 commits into from
Jun 3, 2019

Conversation

ticky
Copy link
Contributor

@ticky ticky commented Aug 22, 2018

This implements use of Intl.NumberFormat over toLocaleString where it is available.

It runs the same feature tests (except for the “locale support” test) on Intl.NumberFormat to determine if it works, and if it suffers from the same bugs as toLocaleString.

Use of Intl.NumberFormat is governed by the same rules as toLocaleString, meaning it is controlled by the useToLocaleString option in addition to its feature tests. I considered either renaming the useToLocaleString option, or adding a second setting, but the intent of the setting seems to be “give me the fallback,” so while I think it would make sense to rename it in future, I didn’t want to do that myself! 😄

Finally, it implements a basic caching mechanism for the Intl.NumberFormat instances. The cachedNumberFormat function maintains a cache of Intl.NumberFormat instances, keyed by their locale and configuration. In this implementation caches on first use when Intl.NumberFormat is used. I have also experimented with a branch (ticky/moment-duration-format@numberformat-support...numberformat-support-multi-use-cache) which caches on the second use of a particular configuration, which gives a similar performance gain when used repeatedly, but doesn’t cache instances which are used only once.

Performance

I’ve compared performance in several ways:

With this patch applied, the existing test suite’s reported run time is reduced from approximately 400-500 milliseconds to 200-300 milliseconds. It varies by browser, of course.

Additionally, I prepared a jsperf comparison between the current npm version, this patch, the aforementioned branch which caches on second use, and the current npm version with useToLocaleString set to `false. Chrome, Firefox and Safari showed these results:

image

Across the board, the fallback formatter implementation is fast, but in all three browsers present, these cache implementations remain competitive, and show a performance gain of somewhere between 3 and 5 times, while maintaining fully-featured locale support.

Finishing Up

I consider this pull request mostly finished, however, I would like some advice on how best to implement tests which specifically target the Intl.NumberFormat implementation: I have observed that the current test suite exercises it in my browsers, but of course this means it no longer exercises toLocaleString support.

I believe that this could be achieved through the introduction of a public useIntlNumberFormat setting (to mirror useToLocaleString), but this would constitute a breaking API change, as existing implementors using useToLocaleString to switch to the fallback would instead end up using Intl.NumberFormat.

fixes #120, likely helps a lot with #107

ticky added a commit to buildkite/frontend that referenced this pull request Aug 22, 2018
This is intended to help improve performance on pages showing large quantities of timers.

Upstream PR is at jsmreese/moment-duration-format#122
@jsmreese
Copy link
Owner

jsmreese commented Nov 2, 2018

Hi Jessica, thank you for this PR!

Things have been pretty crazy recently, but I'd definitely like to get back to this project soon and get your work into a published version.

@ticky
Copy link
Contributor Author

ticky commented Nov 2, 2018

Thanks @jsmreese! I know how it can be sometimes. 😄

For what it’s worth we’ve been running this patch in production since August with no hiccups so far!

@sanex3339
Copy link

Any news?

@ticky
Copy link
Contributor Author

ticky commented Jun 3, 2019

Still running this patch in production, and still happy with it! :)

@jsmreese jsmreese merged commit befbf17 into jsmreese:master Jun 3, 2019
@jsmreese
Copy link
Owner

jsmreese commented Jun 3, 2019

@ticky @sanex3339 I've published version 2.3.0 with this change. Sorry I didn't do that months ago!

@ticky
Copy link
Contributor Author

ticky commented Jun 3, 2019

@jsmreese wonderful, thank you! I know how this stuff can be, though. Thanks for accepting my wall of text 😄

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Intl.NumberFormat support, formatter caching
3 participants