-
Notifications
You must be signed in to change notification settings - Fork 120
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
Conversation
This is intended to help improve performance on pages showing large quantities of timers. Upstream PR is at jsmreese/moment-duration-format#122
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. |
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! |
Any news? |
Still running this patch in production, and still happy with it! :) |
@ticky @sanex3339 I've published version 2.3.0 with this change. Sorry I didn't do that months ago! |
@jsmreese wonderful, thank you! I know how this stuff can be, though. Thanks for accepting my wall of text 😄 |
This implements use of
Intl.NumberFormat
overtoLocaleString
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 astoLocaleString
.Use of
Intl.NumberFormat
is governed by the same rules astoLocaleString
, meaning it is controlled by theuseToLocaleString
option in addition to its feature tests. I considered either renaming theuseToLocaleString
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. ThecachedNumberFormat
function maintains a cache ofIntl.NumberFormat
instances, keyed by their locale and configuration. In this implementation caches on first use whenIntl.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: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 exercisestoLocaleString
support.I believe that this could be achieved through the introduction of a public
useIntlNumberFormat
setting (to mirroruseToLocaleString
), but this would constitute a breaking API change, as existing implementors usinguseToLocaleString
to switch to the fallback would instead end up usingIntl.NumberFormat
.fixes #120, likely helps a lot with #107