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' ;
33import {
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' ;
1313import { APM } from 'instabug-reactnative' ;
1414
15- // CustomComponents
15+ // Custom Components
1616const 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
314442export default ScreenRenderPage ;
0 commit comments