callstack / reassure

Performance testing companion for React and React Native
https://callstack.github.io/reassure/
MIT License
1.27k stars 28 forks source link

[FEATURE] Component render details #173

Open sregg opened 2 years ago

sregg commented 2 years ago

Describe the solution you'd like We started using reassure to measure a particular screen's performance. To be able to render it in the right conditions, we currently render our entire app navigation container with all the necessary context providers (e.g. Jotai, RQ, NativeBase, etc...) and navigate to that problematic screen (i.e. open a modal screen). We running that test, we see that it takes on average 500ms and 20 re-renders. It'd be great to have a way to see what components took the longest and re-rendered the most during that test. Maybe we can specify a list of component names to track (e.g. high level screen components) or track the slowest 10 or only n level deep.

Describe alternatives you've considered We're currently using the Profiler inside ReactDevTools (inside Flipper) to see those component render times. It's pretty good for debugging but it'd be great if we can have them from our automated perf tests as well.

Additional context I'd be happy to contribute if you think this is a feasible feature to implement.

Thanks for this amazing tool. Render (and re-render) issues are the bottleneck of our app right now (we think NativeBase is not helping here). We're working hard on fixing some of these issues but we need a way to prevent future regressions. It's reassuring (pun intended) to see there's a tool that can warn us now.

thymikee commented 2 years ago

Hey @sregg! Thanks for using Reassure. I think I'm not opposed to add such a feature, ideally behind a flag. We already collect details about subsequent render durations in the whole test runs, so there's a precedence to add more detailed data.

Any thoughts @mdjastrzebski @Xiltyn?

mdjastrzebski commented 2 years ago

In general Reassure's goal is to measure performance of the whole test scenarios, as other tools (mainly Dev Tools Profiler in Flipper) are better suited for diagnosing the details for render performance.

That being said, some additional performance hints by Reassure could be useful if implemented in a way that does complicate the primary use case.

From technical pov Reassure wraps whole passed JSX element tree with React.Profiler. It seems that the only way to measure the member components is to wrap each of them in their own React.Profiler HOC. That could be done either by user, by adding <React.Profiler> instances to the element tree, or by Reassure by somehow analysing and modifying the received element tree, based on e.g. names of the components to measure.

@sregg feel free to explore the idea, targeted use cases, potential API, etc.

Couple of random thoughts that might be useful:

thymikee commented 2 years ago

I believe we could also leverage onRender from React.Profiler? https://reactjs.org/docs/profiler.html#onrender-callback

mdjastrzebski commented 2 years ago

We already use onRender from React.Profiler to receive profiler stats, but that does not give use any insights in the child components. Afaik you would need to wrap each relevant descendant component in its own React.Profiler to achieve that.

Xiltyn commented 1 year ago

To comment on the above. Just like @mdjastrzebski have said - it is possible to achieve this result only by wrapping children in React.Profiler HOC as well. That way you could manipulate the data accordingly to produce comparisons between components and such. In fact, we worked with that kind of a setup in the past, but Reassure by itself doesn't support or provide a mechanism for automatic wrapping of components across the repository or its parts. A babel plugin would be the easiest way to achieve the effect, but at the same time it is far from easy :)

At that point I would also be worried about potential impact of all those React.Profilers on performance in general.