jsmreese / moment-duration-format

Format function plugin for the Moment Duration object.
MIT License
967 stars 121 forks source link

Intl.NumberFormat support, formatter caching #120

Closed ticky closed 5 years ago

ticky commented 5 years ago

Currently, this plugin uses toLocaleString (if it’s available and not opted out of) on the numbers it emits. Unfortunately, toLocaleString does a relatively expensive set of locale lookups on every invocation. This is actually something like 98% of the time spent in the method in current browsers according to this test case.

This can be worked around in general by initialising an Intl.NumberFormat and using its format method, which only incurs the locale lookup penalty once.

Perhaps the moment duration formatter instance could keep a cache of formatters for used locales. Then the cached formatter could be taken advantage of in frequent-use cases.

ticky commented 5 years ago

I have a proof of concept of this over at https://github.com/jsmreese/moment-duration-format/compare/master...ticky:numberformat-support. I am not proposing it as a PR yet, as I want to improve the cache mechanism, but early indications are that the performance gains for repeated formats with the same configuration are significant.

This performance test case pits the current npm version against my fork. In my testing, depending on the browser, the npm version manages between 850 and 3000 operations per second, while my fork does achieves between 7500 and 8000 operations per second.

ticky commented 5 years ago

From further testing and refinement, it appears that a fix for this may also address #107; it looks like a lot of the performance trouble in current versions actually stem from the uncached lookups browsers are doing for locale information in toLocaleString calls added in 2.0.0.