From e28aa7d1ab0f8ec21f986231aa752ddde69a97bd Mon Sep 17 00:00:00 2001 From: Samuel Newman Date: Thu, 23 Oct 2025 18:35:37 +0300 Subject: [PATCH] Patch out `PerformanceMonitor` component (#9266) * patch out perf monitor component * make PerformanceMonitor a noop * rm debug stuff --- patches/react-native-reanimated+3.19.1.patch | 389 +++++++++++++++++++ 1 file changed, 389 insertions(+) create mode 100644 patches/react-native-reanimated+3.19.1.patch diff --git a/patches/react-native-reanimated+3.19.1.patch b/patches/react-native-reanimated+3.19.1.patch new file mode 100644 index 0000000000..d3bce8d41f --- /dev/null +++ b/patches/react-native-reanimated+3.19.1.patch @@ -0,0 +1,389 @@ +diff --git a/node_modules/react-native-reanimated/lib/module/component/PerformanceMonitor.js b/node_modules/react-native-reanimated/lib/module/component/PerformanceMonitor.js +index 9c98d6c..70ada9f 100644 +--- a/node_modules/react-native-reanimated/lib/module/component/PerformanceMonitor.js ++++ b/node_modules/react-native-reanimated/lib/module/component/PerformanceMonitor.js +@@ -1,125 +1,5 @@ + 'use strict'; + +-import React, { useEffect, useRef } from 'react'; +-import { StyleSheet, TextInput, View } from 'react-native'; +-import { addWhitelistedNativeProps } from "../ConfigHelper.js"; +-import { createAnimatedComponent } from "../createAnimatedComponent/index.js"; +-import { useAnimatedProps, useFrameCallback, useSharedValue } from "../hook/index.js"; +-function createCircularDoublesBuffer(size) { +- 'worklet'; +- +- return { +- next: 0, +- buffer: new Float32Array(size), +- size, +- count: 0, +- push(value) { +- const oldValue = this.buffer[this.next]; +- const oldCount = this.count; +- this.buffer[this.next] = value; +- this.next = (this.next + 1) % this.size; +- this.count = Math.min(this.size, this.count + 1); +- return oldCount === this.size ? oldValue : null; +- }, +- front() { +- const notEmpty = this.count > 0; +- if (notEmpty) { +- const current = this.next - 1; +- const index = current < 0 ? this.size - 1 : current; +- return this.buffer[index]; +- } +- return null; +- }, +- back() { +- const notEmpty = this.count > 0; +- return notEmpty ? this.buffer[this.next] : null; +- } +- }; +-} +-const DEFAULT_BUFFER_SIZE = 20; +-addWhitelistedNativeProps({ +- text: true +-}); +-const AnimatedTextInput = createAnimatedComponent(TextInput); +-function loopAnimationFrame(fn) { +- let lastTime = 0; +- function loop() { +- requestAnimationFrame(time => { +- if (lastTime > 0) { +- fn(lastTime, time); +- } +- lastTime = time; +- requestAnimationFrame(loop); +- }); +- } +- loop(); +-} +-function getFps(renderTimeInMs) { +- 'worklet'; +- +- return 1000 / renderTimeInMs; +-} +-function completeBufferRoutine(buffer, timestamp) { +- 'worklet'; +- +- timestamp = Math.round(timestamp); +- const droppedTimestamp = buffer.push(timestamp) ?? timestamp; +- const measuredRangeDuration = timestamp - droppedTimestamp; +- return getFps(measuredRangeDuration / buffer.count); +-} +-function JsPerformance({ +- smoothingFrames +-}) { +- const jsFps = useSharedValue(null); +- const totalRenderTime = useSharedValue(0); +- const circularBuffer = useRef(createCircularDoublesBuffer(smoothingFrames)); +- useEffect(() => { +- loopAnimationFrame((_, timestamp) => { +- timestamp = Math.round(timestamp); +- const currentFps = completeBufferRoutine(circularBuffer.current, timestamp); +- +- // JS fps have to be measured every 2nd frame, +- // thus 2x multiplication has to occur here +- jsFps.value = (currentFps * 2).toFixed(0); +- }); +- }, [jsFps, totalRenderTime]); +- const animatedProps = useAnimatedProps(() => { +- const text = 'JS: ' + (jsFps.value ?? 'N/A') + ' '; +- return { +- text, +- defaultValue: text +- }; +- }); +- return +- +- ; +-} +-function UiPerformance({ +- smoothingFrames +-}) { +- const uiFps = useSharedValue(null); +- const circularBuffer = useSharedValue(null); +- useFrameCallback(({ +- timestamp +- }) => { +- if (circularBuffer.value === null) { +- circularBuffer.value = createCircularDoublesBuffer(smoothingFrames); +- } +- timestamp = Math.round(timestamp); +- const currentFps = completeBufferRoutine(circularBuffer.value, timestamp); +- uiFps.value = currentFps.toFixed(0); +- }); +- const animatedProps = useAnimatedProps(() => { +- const text = 'UI: ' + (uiFps.value ?? 'N/A') + ' '; +- return { +- text, +- defaultValue: text +- }; +- }); +- return +- +- ; +-} + /** + * A component that lets you measure fps values on JS and UI threads on both the + * Paper and Fabric architectures. +@@ -127,38 +7,7 @@ function UiPerformance({ + * @param smoothingFrames - Determines amount of saved frames which will be used + * for fps value smoothing. + */ +-export function PerformanceMonitor({ +- smoothingFrames = DEFAULT_BUFFER_SIZE +-}) { +- return +- +- +- ; ++export function PerformanceMonitor() { ++ return null; + } +-const styles = StyleSheet.create({ +- monitor: { +- flexDirection: 'row', +- position: 'absolute', +- backgroundColor: '#0006', +- zIndex: 1000 +- }, +- header: { +- fontSize: 14, +- color: '#ffff', +- paddingHorizontal: 5 +- }, +- text: { +- fontSize: 13, +- fontVariant: ['tabular-nums'], +- color: '#ffff', +- fontFamily: 'monospace', +- paddingHorizontal: 3 +- }, +- container: { +- alignItems: 'center', +- justifyContent: 'center', +- flexDirection: 'row', +- flexWrap: 'wrap' +- } +-}); + //# sourceMappingURL=PerformanceMonitor.js.map +diff --git a/node_modules/react-native-reanimated/src/component/PerformanceMonitor.tsx b/node_modules/react-native-reanimated/src/component/PerformanceMonitor.tsx +index ff8fc8a..34dde79 100644 +--- a/node_modules/react-native-reanimated/src/component/PerformanceMonitor.tsx ++++ b/node_modules/react-native-reanimated/src/component/PerformanceMonitor.tsx +@@ -1,170 +1,5 @@ + 'use strict'; + +-import React, { useEffect, useRef } from 'react'; +-import { StyleSheet, TextInput, View } from 'react-native'; +- +-import { addWhitelistedNativeProps } from '../ConfigHelper'; +-import { createAnimatedComponent } from '../createAnimatedComponent'; +-import type { FrameInfo } from '../frameCallback'; +-import { useAnimatedProps, useFrameCallback, useSharedValue } from '../hook'; +- +-type CircularBuffer = ReturnType; +-function createCircularDoublesBuffer(size: number) { +- 'worklet'; +- +- return { +- next: 0 as number, +- buffer: new Float32Array(size), +- size, +- count: 0 as number, +- +- push(value: number): number | null { +- const oldValue = this.buffer[this.next]; +- const oldCount = this.count; +- this.buffer[this.next] = value; +- +- this.next = (this.next + 1) % this.size; +- this.count = Math.min(this.size, this.count + 1); +- return oldCount === this.size ? oldValue : null; +- }, +- +- front(): number | null { +- const notEmpty = this.count > 0; +- if (notEmpty) { +- const current = this.next - 1; +- const index = current < 0 ? this.size - 1 : current; +- return this.buffer[index]; +- } +- return null; +- }, +- +- back(): number | null { +- const notEmpty = this.count > 0; +- return notEmpty ? this.buffer[this.next] : null; +- }, +- }; +-} +- +-const DEFAULT_BUFFER_SIZE = 20; +-addWhitelistedNativeProps({ text: true }); +-const AnimatedTextInput = createAnimatedComponent(TextInput); +- +-function loopAnimationFrame(fn: (lastTime: number, time: number) => void) { +- let lastTime = 0; +- +- function loop() { +- requestAnimationFrame((time) => { +- if (lastTime > 0) { +- fn(lastTime, time); +- } +- lastTime = time; +- requestAnimationFrame(loop); +- }); +- } +- +- loop(); +-} +- +-function getFps(renderTimeInMs: number): number { +- 'worklet'; +- return 1000 / renderTimeInMs; +-} +- +-function completeBufferRoutine( +- buffer: CircularBuffer, +- timestamp: number +-): number { +- 'worklet'; +- timestamp = Math.round(timestamp); +- +- const droppedTimestamp = buffer.push(timestamp) ?? timestamp; +- +- const measuredRangeDuration = timestamp - droppedTimestamp; +- +- return getFps(measuredRangeDuration / buffer.count); +-} +- +-function JsPerformance({ smoothingFrames }: { smoothingFrames: number }) { +- const jsFps = useSharedValue(null); +- const totalRenderTime = useSharedValue(0); +- const circularBuffer = useRef( +- createCircularDoublesBuffer(smoothingFrames) +- ); +- +- useEffect(() => { +- loopAnimationFrame((_, timestamp) => { +- timestamp = Math.round(timestamp); +- +- const currentFps = completeBufferRoutine( +- circularBuffer.current, +- timestamp +- ); +- +- // JS fps have to be measured every 2nd frame, +- // thus 2x multiplication has to occur here +- jsFps.value = (currentFps * 2).toFixed(0); +- }); +- }, [jsFps, totalRenderTime]); +- +- const animatedProps = useAnimatedProps(() => { +- const text = 'JS: ' + (jsFps.value ?? 'N/A') + ' '; +- return { text, defaultValue: text }; +- }); +- +- return ( +- +- +- +- ); +-} +- +-function UiPerformance({ smoothingFrames }: { smoothingFrames: number }) { +- const uiFps = useSharedValue(null); +- const circularBuffer = useSharedValue(null); +- +- useFrameCallback(({ timestamp }: FrameInfo) => { +- if (circularBuffer.value === null) { +- circularBuffer.value = createCircularDoublesBuffer(smoothingFrames); +- } +- +- timestamp = Math.round(timestamp); +- +- const currentFps = completeBufferRoutine(circularBuffer.value, timestamp); +- +- uiFps.value = currentFps.toFixed(0); +- }); +- +- const animatedProps = useAnimatedProps(() => { +- const text = 'UI: ' + (uiFps.value ?? 'N/A') + ' '; +- return { text, defaultValue: text }; +- }); +- +- return ( +- +- +- +- ); +-} +- +-export type PerformanceMonitorProps = { +- /** +- * Sets amount of previous frames used for smoothing at highest expectedFps. +- * +- * Automatically scales down at lower frame rates. +- * +- * Affects jumpiness of the FPS measurements value. +- */ +- smoothingFrames?: number; +-}; +- + /** + * A component that lets you measure fps values on JS and UI threads on both the + * Paper and Fabric architectures. +@@ -172,40 +7,6 @@ export type PerformanceMonitorProps = { + * @param smoothingFrames - Determines amount of saved frames which will be used + * for fps value smoothing. + */ +-export function PerformanceMonitor({ +- smoothingFrames = DEFAULT_BUFFER_SIZE, +-}: PerformanceMonitorProps) { +- return ( +- +- +- +- +- ); ++export function PerformanceMonitor() { ++ return null; + } +- +-const styles = StyleSheet.create({ +- monitor: { +- flexDirection: 'row', +- position: 'absolute', +- backgroundColor: '#0006', +- zIndex: 1000, +- }, +- header: { +- fontSize: 14, +- color: '#ffff', +- paddingHorizontal: 5, +- }, +- text: { +- fontSize: 13, +- fontVariant: ['tabular-nums'], +- color: '#ffff', +- fontFamily: 'monospace', +- paddingHorizontal: 3, +- }, +- container: { +- alignItems: 'center', +- justifyContent: 'center', +- flexDirection: 'row', +- flexWrap: 'wrap', +- }, +-});