Skip to content

Commit ca77692

Browse files
AndrewAminInstabugMoKamall
authored andcommitted
update the sample app
1 parent 0f9365f commit ca77692

File tree

1 file changed

+186
-58
lines changed

1 file changed

+186
-58
lines changed

examples/default/src/screens/apm/ScreenRender.tsx

Lines changed: 186 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
1-
import { NativeStackScreenProps } from '@react-navigation/native-stack';
2-
import React, { useState, useEffect, useRef } from 'react';
1+
import type { NativeStackScreenProps } from '@react-navigation/native-stack';
2+
import React, { useEffect, useRef, useState } from 'react';
33
import {
4-
View,
5-
Text,
4+
Animated,
5+
SafeAreaView,
6+
ScrollView,
67
StyleSheet,
8+
Text,
79
TouchableOpacity,
8-
ScrollView,
9-
SafeAreaView,
10-
Animated,
10+
View,
1111
} from 'react-native';
12-
import { HomeStackParamList } from '../../navigation/HomeStack';
12+
import type { HomeStackParamList } from '../../navigation/HomeStack';
1313
import { APM } from 'instabug-reactnative';
1414

15-
// CustomComponents
15+
// Custom Components
1616
const ScreenRenderSwitch: React.FC = () => {
1717
const [isEnabled, setIsEnabled] = useState(false);
1818

@@ -31,46 +31,45 @@ const ScreenRenderSwitch: React.FC = () => {
3131
);
3232
};
3333

34-
const AnimatedBox: React.FC<{ isBlocking: boolean }> = ({ isBlocking }) => {
34+
const AnimatedBox: React.FC<{ isBlocking: boolean; blockingIntensity: number }> = ({
35+
isBlocking,
36+
blockingIntensity,
37+
}) => {
3538
const [counter, setCounter] = useState(0);
39+
const [layoutThrasher, setLayoutThrasher] = useState(0);
3640
const animatedValue = useRef(new Animated.Value(0)).current;
3741
const intervalRef = useRef<NodeJS.Timeout | null>(null);
3842

39-
// Continuous animation
43+
// Continuous animation - Use native driver for native thread work
4044
useEffect(() => {
4145
const animation = Animated.loop(
4246
Animated.sequence([
4347
Animated.timing(animatedValue, {
4448
toValue: 1,
4549
duration: 1000,
46-
useNativeDriver: true,
50+
useNativeDriver: true, // Native driver for native thread
4751
}),
4852
Animated.timing(animatedValue, {
4953
toValue: 0,
5054
duration: 1000,
51-
useNativeDriver: true,
55+
useNativeDriver: true, // Native driver for native thread
5256
}),
5357
]),
5458
);
5559
animation.start();
5660

5761
return () => animation.stop();
58-
}, []);
62+
}, [animatedValue]);
5963

60-
// High frequency counter updates to force re-renders
64+
// High frequency counter updates
6165
useEffect(() => {
6266
intervalRef.current = setInterval(() => {
63-
setCounter((prev) => {
64-
// This is where we block if isBlocking is true
65-
if (isBlocking) {
66-
const startTime = Date.now();
67-
// Block for 100ms every render cycle
68-
while (Date.now() - startTime < 100) {
69-
// Busy wait - this will cause visible frozen frames
70-
}
71-
}
72-
return prev + 1;
73-
});
67+
setCounter((prev) => prev + 1);
68+
69+
// Layout thrashing to block native thread
70+
if (isBlocking) {
71+
setLayoutThrasher((prev) => prev + 1);
72+
}
7473
}, 16); // ~60fps updates
7574

7675
return () => {
@@ -85,19 +84,121 @@ const AnimatedBox: React.FC<{ isBlocking: boolean }> = ({ isBlocking }) => {
8584
outputRange: [0, 100],
8685
});
8786

87+
const getStatusText = () => {
88+
if (!isBlocking) {
89+
return 'Running Smoothly';
90+
}
91+
if (blockingIntensity === 1) {
92+
return 'SLOW NATIVE RENDERING!';
93+
}
94+
if (blockingIntensity === 2) {
95+
return 'FROZEN NATIVE THREAD!';
96+
}
97+
return 'BLOCKING NATIVE THREAD!';
98+
};
99+
100+
const getBoxColor = () => {
101+
if (!isBlocking) {
102+
return '#4ECDC4';
103+
}
104+
if (blockingIntensity === 1) {
105+
return '#FFB347';
106+
} // Orange for slow
107+
if (blockingIntensity === 2) {
108+
return '#FF6B6B';
109+
} // Red for frozen
110+
return '#FF6B6B';
111+
};
112+
113+
// Generate many layout-heavy elements to stress native thread
114+
const generateHeavyNativeElements = () => {
115+
if (!isBlocking) return null;
116+
117+
const elementCount = blockingIntensity === 1 ? 50 : 200; // More elements = more native work
118+
119+
return Array.from({ length: elementCount }, (_, i) => (
120+
<View
121+
key={`heavy-${i}-${layoutThrasher}`} // Force remount on layout thrash
122+
style={{
123+
position: 'absolute',
124+
left: (i * 3) % 300,
125+
top: (i * 2) % 200,
126+
width: 20 + (layoutThrasher % 30), // Constantly changing dimensions
127+
height: 20 + ((layoutThrasher * 2) % 30),
128+
backgroundColor: `hsl(${(i * 10 + layoutThrasher) % 360}, 70%, 60%)`,
129+
borderRadius: 5 + (layoutThrasher % 10), // Constantly changing border radius
130+
transform: [
131+
{ rotate: `${(layoutThrasher * 5 + i * 10) % 360}deg` },
132+
{ scale: 0.5 + (layoutThrasher % 10) / 20 }, // Constantly changing scale
133+
],
134+
opacity: 0.3 + (layoutThrasher % 40) / 100, // Constantly changing opacity
135+
borderWidth: 1 + (layoutThrasher % 3), // Force layout recalculation
136+
borderColor: `hsl(${(layoutThrasher * 7) % 360}, 50%, 40%)`,
137+
}}
138+
/>
139+
));
140+
};
141+
88142
return (
89143
<View style={styles.animatedContainer}>
90144
<Text style={styles.counterText}>Frame Counter: {counter}</Text>
91-
<Animated.View
92-
style={[
93-
styles.animatedBox,
94-
{
145+
<Text style={[styles.statusText, isBlocking && styles.statusTextAlert]}>
146+
Status: {getStatusText()}
147+
</Text>
148+
149+
{/* Native thread heavy work area */}
150+
<View style={styles.nativeWorkArea}>
151+
<Animated.View
152+
style={{
153+
backgroundColor: getBoxColor(),
95154
transform: [{ translateX }],
96-
backgroundColor: isBlocking ? '#FF6B6B' : '#4ECDC4',
97-
},
98-
]}>
99-
<Text style={styles.animatedBoxText}>{isBlocking ? 'FROZEN!' : 'Smooth'}</Text>
100-
</Animated.View>
155+
width: 60,
156+
height: 60,
157+
borderRadius: 30,
158+
justifyContent: 'center',
159+
alignItems: 'center',
160+
}}>
161+
<Text style={styles.animatedBoxText}>
162+
{blockingIntensity === 1 ? 'Slow!' : blockingIntensity === 2 ? 'Frozen!' : 'Smooth'}
163+
</Text>
164+
</Animated.View>
165+
166+
{/* Heavy native rendering elements */}
167+
{generateHeavyNativeElements()}
168+
</View>
169+
170+
{/* Additional native-heavy components */}
171+
{isBlocking && (
172+
<View style={styles.heavyNativeSection}>
173+
{/* Multiple ScrollViews to stress native scrolling */}
174+
<ScrollView
175+
style={styles.miniScrollView}
176+
showsVerticalScrollIndicator={false}
177+
contentContainerStyle={{ height: 1000 }}>
178+
{Array.from({ length: 100 }, (_, i) => (
179+
<View
180+
key={`scroll-${i}-${layoutThrasher}`}
181+
style={{
182+
height: 10,
183+
backgroundColor: `hsl(${(i * 20 + layoutThrasher) % 360}, 60%, 70%)`,
184+
marginVertical: 1,
185+
}}
186+
/>
187+
))}
188+
</ScrollView>
189+
190+
{/* Text that forces layout recalculation */}
191+
<Text
192+
style={{
193+
fontSize: 8 + (layoutThrasher % 10),
194+
color: `hsl(${layoutThrasher % 360}, 70%, 50%)`,
195+
textAlign: 'center',
196+
lineHeight: 12 + (layoutThrasher % 8),
197+
}}>
198+
Layout Thrashing Text: {layoutThrasher}
199+
</Text>
200+
</View>
201+
)}
101202
</View>
102203
);
103204
};
@@ -124,24 +225,12 @@ const ScreenRenderPage: React.FC<NativeStackScreenProps<HomeStackParamList, 'Scr
124225
navigation,
125226
}) => {
126227
const [isBlocking, setIsBlocking] = useState(false);
228+
const [blockingIntensity, setBlockingIntensity] = useState(0); // 0 = none, 1 = slow, 2 = frozen
127229
const blockingTimeoutRef = useRef<NodeJS.Timeout | null>(null);
128230

129-
const triggerSlowFrames = (): void => {
130-
setIsBlocking(true);
131-
132-
// Clear any existing timeout
133-
if (blockingTimeoutRef.current) {
134-
clearTimeout(blockingTimeoutRef.current);
135-
}
136-
137-
// Stop blocking after 3 seconds
138-
blockingTimeoutRef.current = setTimeout(() => {
139-
setIsBlocking(false);
140-
}, 500);
141-
};
142-
143231
const triggerFrozenFrames = (): void => {
144232
setIsBlocking(true);
233+
setBlockingIntensity(2); // Frozen frames mode
145234

146235
// Clear any existing timeout
147236
if (blockingTimeoutRef.current) {
@@ -151,7 +240,8 @@ const ScreenRenderPage: React.FC<NativeStackScreenProps<HomeStackParamList, 'Scr
151240
// Stop blocking after 5 seconds
152241
blockingTimeoutRef.current = setTimeout(() => {
153242
setIsBlocking(false);
154-
}, 3000);
243+
setBlockingIntensity(0);
244+
}, 5000);
155245
};
156246

157247
const navigateToComplexPage = (): void => {
@@ -174,19 +264,13 @@ const ScreenRenderPage: React.FC<NativeStackScreenProps<HomeStackParamList, 'Scr
174264

175265
<View style={styles.spacer} />
176266

177-
<AnimatedBox isBlocking={isBlocking} />
267+
<AnimatedBox isBlocking={isBlocking} blockingIntensity={blockingIntensity} />
178268

179269
<View style={styles.largeSpacer} />
180270

181271
<View style={styles.buttonContainer}>
182272
<InstabugButton
183-
text={isBlocking ? 'Frames are Delayed! (Wait...)' : 'Trigger Slow Frames (500ms)'}
184-
onPress={triggerSlowFrames}
185-
disabled={isBlocking}
186-
/>
187-
188-
<InstabugButton
189-
text={isBlocking ? 'Frames are Delayed! (Wait...)' : 'Trigger Frozen Frames (3000ms)'}
273+
text={isBlocking ? 'Frames are Delayed! (Wait...)' : 'Trigger Frozen Frames (5s)'}
190274
onPress={triggerFrozenFrames}
191275
disabled={isBlocking}
192276
/>
@@ -309,6 +393,50 @@ const styles = StyleSheet.create({
309393
fontWeight: '600',
310394
textAlign: 'center',
311395
},
396+
statusText: {
397+
fontSize: 16,
398+
color: '#666',
399+
marginBottom: 10,
400+
},
401+
statusTextAlert: {
402+
color: '#FF6B6B', // Red for alert
403+
fontWeight: 'bold',
404+
},
405+
additionalElements: {
406+
flexDirection: 'row',
407+
flexWrap: 'wrap',
408+
justifyContent: 'center',
409+
marginTop: 20,
410+
},
411+
smallBox: {
412+
width: 30,
413+
height: 30,
414+
margin: 5,
415+
borderRadius: 15,
416+
},
417+
nativeWorkArea: {
418+
position: 'relative',
419+
width: 200,
420+
height: 200,
421+
backgroundColor: '#f0f0f0',
422+
borderRadius: 10,
423+
justifyContent: 'center',
424+
alignItems: 'center',
425+
marginVertical: 10,
426+
borderWidth: 1,
427+
borderColor: '#ccc',
428+
},
429+
heavyNativeSection: {
430+
marginTop: 20,
431+
alignItems: 'center',
432+
},
433+
miniScrollView: {
434+
width: '100%',
435+
height: 100,
436+
backgroundColor: '#e0e0e0',
437+
borderRadius: 8,
438+
marginBottom: 10,
439+
},
312440
});
313441

314442
export default ScreenRenderPage;

0 commit comments

Comments
 (0)