You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The demo renders two forms: A contains 100 NumericInputs with constant values and a Slider, B is the same but with InputGroups. All props to the NumericInputs are literal constants. (Using 100 inputs just to exaggerate the effect, but it's noticeable even in much smaller forms.)
Steps to reproduce
Open the demo in Firefox (seems to be less of an issue in Chrome).
Drag the sliders around quickly.
Actual behavior
In Firefox, the form (and slider) with NumericInputs renders very slowly.
Expected behavior
Both sliders should move smoothly.
Cause
Looking at the Firefox profiler, the issue seems to be that React is still calling NumericInput.getDerivedStateFromProps even when props don't change. That calls Number.prototype.toLocaleString numerous times, which seems to be super slow on Firefox:
In our own app, NumericInput rendering takes up ~15% of CPU time when a form containing any NumericInputs is re-rendered. This time isn't visible at all in the React profiler, as the component's aren't rendering - I believe the time is counted against the parent components instead!
Possible solution
Since getDerivedStateFromProps doesn't use sanitizedValue unless min or max are changed, moving its computation inside if (didBoundsChange) should be a trivial improvement:
Furthermore, most of the time is spent in isFloatingPointNumericCharacter. One could probably cache the decimal regexes per-locale for a decent perf boost. (Currently, it's re-computing the regex for each character of the input string.)
I'm happy to write a PR if you agree with the suggestions.
The text was updated successfully, but these errors were encountered:
Number.prototype.toLocaleString is relatively slow on Firefox, and is
currently heavily used by NumericInput.getDerivedStateFromProps (which
further calls isFloatingPointNumericCharacter on each character of the
current value).
This improves the situation in two ways:
- Caches the regexes generated by isFloatingPointNumericCharacter
- Only calls roundAndClampValue when necessary in getDerivedStateFromProps
Environment
Code Sandbox
https://codepen.io/PurkkaKoodari/pen/mdxMNKb
The demo renders two forms:
A
contains 100NumericInput
s with constant values and aSlider
,B
is the same but withInputGroup
s. All props to theNumericInput
s are literal constants. (Using 100 inputs just to exaggerate the effect, but it's noticeable even in much smaller forms.)Steps to reproduce
Actual behavior
In Firefox, the form (and slider) with
NumericInput
s renders very slowly.Expected behavior
Both sliders should move smoothly.
Cause
Looking at the Firefox profiler, the issue seems to be that React is still calling
NumericInput.getDerivedStateFromProps
even when props don't change. That callsNumber.prototype.toLocaleString
numerous times, which seems to be super slow on Firefox:In our own app,
NumericInput
rendering takes up ~15% of CPU time when a form containing any NumericInputs is re-rendered. This time isn't visible at all in the React profiler, as the component's aren't rendering - I believe the time is counted against the parent components instead!Possible solution
Since
getDerivedStateFromProps
doesn't usesanitizedValue
unlessmin
ormax
are changed, moving its computation insideif (didBoundsChange)
should be a trivial improvement:https://github.com/palantir/blueprint/blob/develop/packages/core/src/components/forms/numericInput.tsx#L235-L245
Furthermore, most of the time is spent in
isFloatingPointNumericCharacter
. One could probably cache the decimal regexes per-locale for a decent perf boost. (Currently, it's re-computing the regex for each character of the input string.)I'm happy to write a PR if you agree with the suggestions.
The text was updated successfully, but these errors were encountered: