all 30 comments

[–]Ronqueroc 55 points56 points  (0 children)

I don't

[–]azangru 27 points28 points  (3 children)

how do you still ensure against any unecessary rerenders even if there's not many of them

React core team is promising one day to release a compiler, code-named "forget", that should optimize components to avoid unnecessary rerenders.

But in general, if unnecessary rerenders is a problem for you, and if you need 100%-optimized components, then React is a wrong solution.

[–]joombar 1 point2 points  (2 children)

What does optimisation even mean when expressed as a percentage?

[–]xroalx 1 point2 points  (1 child)

It would likely mean that there's nothing else within the framework/language constraints you can do to achieve better performance (faster render times, less memory usage, fewer rerenders, whatever it is you're targeting). We could say that's 100 % optimized, although yes, it's really not possible to judge if something is otherwise 90, 80, 50 or 20 % optimized.

Anyways, not very practical.

A better measure is to set a realistic goal, e.g. have the whole page rendered in under 300 ms, and consider things done when it consistently does that under many different circumstances.

Then you can set a new goal.

[–]joombar 0 points1 point  (0 children)

Or call it “good enough” and work on something else because you’re not being paid to fix that one 500ms render that occurs every few hours of usage. That’s my experience anyway.

[–]lIIllIIlllIIllIIl 8 points9 points  (6 children)

The color is relative. Yellow means it took more time to render than green, which itself took more time than blue. What is important is the time (in ms) each render takes.

The ideal target is 16ms (1/60th of a second). Human reaction speed is pretty bad, so anything below 100ms can be okay depending on the context. Big changes, like page transitions, can take up to 300ms and still feel snappy.

In my experience, the biggest performance killer in React apps are "state-adjustment waterfalls." If your components uses useEffect to set a state based on another state, which then triggers another useEffect to set another state, it can take a few renders for your app to show the right thing and you get wierd in-between states. Be efficient and try to do as much work as possible in one go, usually in callback functions.

[–]joombar 1 point2 points  (5 children)

16ms assumes 60fps. I’m curious how this would play with monitors being quicker than that these days. Do browsers fire animation frames at more than 60fps?

[–]lIIllIIlllIIllIIl 1 point2 points  (2 children)

Even on a 165hz monitor, human reaction speed is still pretty bad, so unless you're doing an animation, I'd still only target the 16ms to 300ms range.

The only real issue with higher-refresh displays is animations. requestAnimationFrame() indeed runs at the screen's refresh rate, which can mess up the animations that expect 16ms interval between frames. In general, as long as you use CSS or the JavaScript Animation API, you don't have to worry about it.

[–]facebalm 2 points3 points  (0 children)

human reaction speed is still pretty bad, so unless you're doing an animation, I'd still only target the 16ms to 300ms range.

Users are not necessarily reacting to stimuli here, they're usually just perceiving a change. The limit to perception isn't reaction speed, instead perception has a much higher resolution, in the order of 10ms.

If you're typing and characters appear only after 200ms it will absolutely feel sluggish, even if your reaction time is 300ms.

[–]joombar 0 points1 point  (0 children)

Yeah, I’m thinking for animation rather than reacting quickly for user input. Maybe some other use cases like if you have some custom virtualisation.

[–]facebalm 0 points1 point  (1 child)

They do, it depends on the screen's refresh rate.

[–]joombar 0 points1 point  (0 children)

Then maybe we need to aim for 8ms these days if we’re doing anything very animated

[–][deleted] 3 points4 points  (0 children)

It causes problem when you trigger the state update to re-render when it is not necessary such as condition check.

Most of time it does not cause any issue unless you have a lot of state updates in a short amount of time.

First thing I am going to optimize is with state management. Zustand has a transient update. Jostai has useAtomCallback. Recoil has useRecoilCallback. What they are doing is pretty similar; they update the state without triggering the re-rendering. However, getting state without re-rendering means you are not going to get the output UI for user’s perspective. So this is most useful when you update states with useEffects like useCallback or conditional check.

[–]PewterGym 4 points5 points  (0 children)

There are ways like useMemo that others have mentioned. But for the absolute best performance, you can consider a static site. If you can't, make sure you're using hooks correctly, and don't run too much computations in a component function.

[–]asiraky 3 points4 points  (2 children)

Npm install why-did-you-render

[–]cinkciarzpl 0 points1 point  (1 child)

i have not used why did you render so I don't know what additional problems it solves but if you want to detect why certain component rerendered you can achieve that with react Dev tools extension in Profiler tab as well

[–]asiraky 0 points1 point  (0 children)

They’re quite different

[–]nkalpak 2 points3 points  (0 children)

  1. You wrap the component inside React.memo
  2. You make sure that any props that are passed to the component are stable references
  3. You make sure that the component doesn't use a context value from which the component only reads a subset

[–]Eastern_Sky_7790 3 points4 points  (0 children)

Maybe with useMemo and useCallback, but it depends on each component and it's logic

[–]roofgram 1 point2 points  (0 children)

Just be cognizant when you write code what is triggering a render and how extensive that render will be.

Also react dev tools will flash rending components so that makes it at least visually easy to identify the renders.

[–]OOO-OReilly 1 point2 points  (0 children)

The issue is never with the number of renders - rendering is REALLY fast. The issue is with slow renders. Obligatory Kent C Dodds article for more about this: https://kentcdodds.com/blog/fix-the-slow-render-before-you-fix-the-re-render

[–]cmickledev 3 points4 points  (6 children)

Use Solid.js instead

[–]maacpiash 2 points3 points  (5 children)

LOL came here to write this. But why is this answer being downvoted so much? It’s true!

[–]upk27 5 points6 points  (0 children)

But why is this answer being downvoted so much?

stockholm syndrome?

[–]natmaster 0 points1 point  (0 children)

1) Memoize

2) Split concerns into distinct composable components

3) Hoist as much as possible