blueprint icon indicating copy to clipboard operation
blueprint copied to clipboard

NumericInput causing significant performance drops in Firefox

Open PurkkaKoodari opened this issue 2 years ago • 1 comments

Environment

  • Package version(s): 4.6.1
  • Operating System: Tested on Windows 10
  • Browser name and version: Firefox 102

Code Sandbox

https://codepen.io/PurkkaKoodari/pen/mdxMNKb

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

  1. Open the demo in Firefox (seems to be less of an issue in Chrome).
  2. 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:

Firefox profiler results

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:

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.

PurkkaKoodari avatar Jul 26 '22 12:07 PurkkaKoodari

Thanks for the detailed performance report. I'm definitely open to PRs to improve component perf here.

adidahiya avatar Jul 26 '22 13:07 adidahiya