Closed dinkinflickaa closed 7 months ago
Layout effects are permitted when a component should re-size its contents before the browser paints. (This is done to avoid flickering/shifting.)
The main problem in the above screenshot is either (a) something in your code is triggering repeated renders+updates or (b) one or more of your components is doing too much work in render to be able to update quickly. Hard to tell which.
Layout effects are permitted when a component should re-size its contents before the browser paints.
@bvaughn In this case aren't we triggering resize manually though? See: https://github.com/bvaughn/react-virtualized-auto-sizer/blob/master/src/AutoSizer.ts#L65C1-L66C1
The main problem in the above screenshot is either (a) something in your code is triggering repeated renders+updates or (b) one or more of your components is doing too much work in render to be able to update quickly
The screenshot is taken from codesanbox link's browser trace. https://codesandbox.io/p/sandbox/react-class-forked-5ffvgl?file=%2Fsrc%2Findex.js
All it does is:
componentDidMount
So there aren't repeated re-renders but paint is delayed here because it has a lot of slow side effects which have to be flushed synchronously because of the nested update. This can be quite terrible when you are unmounting a lot of components before mounting AutoSizer
I'm not sure what to say, except...don't re-render 10k components like that 😄 It's never going to be performant. Switching from a layout effect to a passive effect will not make a difference in many cases, (often something else will trigger a sync update which will cause React to also flush passive effects before proceeding). And even if that's not the case, it's still going to take a ton of CPU time.
Layout effects are for layout (resizing and positioning) which is exactly what this component does.
Autosizer sets state in componentDidMount phase which will block browser from repainting. This can be a big performance bottleneck.
Here is a codesandbox to demonstrate how changing state in componentDidMount phase can take longer to paint
https://codesandbox.io/p/sandbox/react-class-forked-5ffvgl?file=%2Fsrc%2Findex.js
Trace with state change inside
componentDidMount
Trace without state change inside
componentDidMount
Has anyone else run into this? Can we get the state changes before the first rather and avoid a nested update?