From 9a57d2a538e4acf112069aa3b6ba37d615ede758 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 19 Nov 2024 02:20:58 +0000 Subject: Add Profiler build for Android (#6510) --- metro.config.js | 14 +++++++++++ package.json | 2 ++ src/App.native.tsx | 71 ++++++++++++++++++++++++++++------------------------- src/AppProfiler.tsx | 29 ++++++++++++++++++++++ 4 files changed, 82 insertions(+), 34 deletions(-) create mode 100644 src/AppProfiler.tsx diff --git a/metro.config.js b/metro.config.js index e6a6676f0..d083f2a84 100644 --- a/metro.config.js +++ b/metro.config.js @@ -9,6 +9,11 @@ cfg.resolver.sourceExts = process.env.RN_SRC_EXT if (cfg.resolver.resolveRequest) { throw Error('Update this override because it is conflicting now.') } + +if (process.env.BSKY_PROFILE) { + cfg.cacheVersion += ':PROFILE' +} + cfg.resolver.resolveRequest = (context, moduleName, platform) => { // HACK: manually resolve a few packages that use `exports` in `package.json`. // A proper solution is to enable `unstable_enablePackageExports` but this needs careful testing. @@ -29,6 +34,15 @@ cfg.resolver.resolveRequest = (context, moduleName, platform) => { if (moduleName === '@ipld/dag-cbor') { return context.resolveRequest(context, '@ipld/dag-cbor/src', platform) } + if (process.env.BSKY_PROFILE) { + if (moduleName.endsWith('ReactNativeRenderer-prod')) { + return context.resolveRequest( + context, + moduleName.replace('-prod', '-profiling'), + platform, + ) + } + } return context.resolveRequest(context, moduleName, platform) } diff --git a/package.json b/package.json index 2dc5210b7..30c2be2b3 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,8 @@ "postinstall": "patch-package && yarn intl:compile", "prebuild": "expo prebuild --clean", "android": "expo run:android", + "android:prod": "expo run:android --variant release", + "android:profile": "BSKY_PROFILE=1 expo run:android --variant release", "ios": "expo run:ios", "web": "expo start --web", "use-build-number": "./scripts/useBuildNumberEnv.sh", diff --git a/src/App.native.tsx b/src/App.native.tsx index 668fb91fc..9b2940aa9 100644 --- a/src/App.native.tsx +++ b/src/App.native.tsx @@ -69,6 +69,7 @@ import {Provider as PortalProvider} from '#/components/Portal' import {Splash} from '#/Splash' import {BottomSheetProvider} from '../modules/bottom-sheet' import {BackgroundNotificationPreferencesProvider} from '../modules/expo-background-notification-handler/src/BackgroundNotificationHandlerProvider' +import {AppProfiler} from './AppProfiler' SplashScreen.preventAutoHideAsync() @@ -184,40 +185,42 @@ function App() { * that is set up in the InnerApp component above. */ return ( - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ) } diff --git a/src/AppProfiler.tsx b/src/AppProfiler.tsx new file mode 100644 index 000000000..31a4cc54e --- /dev/null +++ b/src/AppProfiler.tsx @@ -0,0 +1,29 @@ +import React, {Profiler} from 'react' + +// Don't let it get stripped out in profiling builds (which apply production Babel preset). +const log = (global as any)['con' + 'sole'].log + +function onRender(id: string, phase: string, actualDuration: number) { + if (!__DEV__) { + // This block of code will exist in the production build of the app. + // However, only profiling builds of React call `onRender` so it's dead code in actual production. + const message = ` ${id}:${phase} ${ + actualDuration > 500 + ? '(╯°□°)╯ ' + : actualDuration > 100 + ? '[!!] ' + : actualDuration > 16 + ? '[!] ' + : '' + }${Math.round(actualDuration)}ms` + log(message) + } +} + +export function AppProfiler({children}: {children: React.ReactNode}) { + return ( + + {children} + + ) +} -- cgit 1.4.1