Attempting to measure re-rending times causes an exception.
Opened this issue · 1 comments
Current behavior
Attempting to measure re-rending times causes an exception.
Expected behavior
The library should be able to measure re-render times as advised in https://shopify.github.io/react-native-performance/docs/fundamentals/measuring-render-times.
To Reproduce
Here is the repro https://github.com/GiridharKarnik/RerenderFlow.
Platform:
- iOS
- Android
Packages
Which packages are affected by the issue?
- @shopify/react-native-performance
- @shopify/react-native-performance-lists-profiler
- flipper-plugin-shopify-react-native-performance
- @shopify/react-native-performance-navigation
- @shopify/react-native-performance-navigation-bottom-tabs
- @shopify/react-native-performance-navigation-drawer
Environment
The package versions can be referred from the repo link pasted above.
- I've removed the packages that I don't use
package | version |
---|---|
@shopify/react-native-performance | 4.1.2 |
@shopify/react-native-performance-lists-profiler | - |
flipper-plugin-shopify-react-native-performance | - |
@shopify/react-native-performance-navigation | - |
@shopify/react-native-performance-navigation-bottom-tabs | - |
@shopify/react-native-performance-navigation-drawer | - |
@react-navigation/native | - |
@react-navigation/bottom-tabs | - |
@react-navigation/drawer | - |
@react-navigation/stack | - |
react-native | 0.72.4 |
Additional info
The app contains a straightforward screen with a button that increments a state, triggering a re-render. The root of the App is wrapped with <PerformanceProfiler />
content layer.
import React, {useState} from 'react';
import {
SafeAreaView,
StyleSheet,
Text,
TouchableOpacity,
View,
useColorScheme,
} from 'react-native';
import {Colors} from 'react-native/Libraries/NewAppScreen';
import {
useResetFlow,
PerformanceMeasureView,
} from '@shopify/react-native-performance';
function ScreenA(): JSX.Element {
const {resetFlow, componentInstanceId} = useResetFlow();
const [resetId, setResetId] = useState(0);
const reRenderScreen = () => {
resetFlow({
destination: 'ScreenA',
});
console.log('Re-rendering screen');
setResetId(resetId + 1);
};
return (
<PerformanceMeasureView
componentInstanceId={componentInstanceId}
screenName="ScreenA"
interactive={true}>
<SafeAreaView>
<View style={styles.contentsContainer}>
<TouchableOpacity style={styles.button} onPress={reRenderScreen}>
<Text style={styles.rerenderButton}>Rerender</Text>
</TouchableOpacity>
<View style={styles.resetCounterContainer}>
<Text style={styles.resetId}>{resetId}</Text>
</View>
</View>
</SafeAreaView>
</PerformanceMeasureView>
);
}
const styles = StyleSheet.create({
...
});
export default ScreenA;
When I press the Rerender button I get the following error
ERROR RenderTimeoutError: Screen 'ScreenA' failed to render in 5000 milliseconds. One of the following could happen:
1. You notified the profiler of the navigation-start event via the useStartProfiler hook, but forgot to notify of the render-completion event via <PerformanceMeasureView/>
Read the usage here: https://shopify.github.io/react-native-performance/fundamentals/measuring-render-times.
2. You use useStartProfiler hook instead of useResetFlow hook when re-render is occurring because the flow is essentially being restarted.
Read the usage here: https://shopify.github.io/react-native-performance/fundamentals/measuring-render-times#3-measuring-screen-re-render-times.
The state at timeout was: {
"name": "Started",
"destinationScreen": "ScreenA",
"componentInstanceId": "0",
"previousState": "Rendered",
"timestamp": {
"jsTimestamp": 1693757078630
},
"operationsSnapshot": {
"operationTimestamps": {}
},
"ongoingOperations": {
"operationTimestamps": {}
},
"sourceScreen": "ScreenA",
"type": "flow_reset"
}.
Not sure what is wrong with the code, any help would be much appreciated.
hi, do you have any solution for this?