diff options
author | dan <dan.abramov@gmail.com> | 2024-11-19 02:20:58 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-11-19 02:20:58 +0000 |
commit | 9a57d2a538e4acf112069aa3b6ba37d615ede758 (patch) | |
tree | af2881c9325cccb97770d4c54a6a0861949d8ff2 | |
parent | 7b6c18272385494145676e42cbe922bde7ceae6b (diff) | |
download | voidsky-9a57d2a538e4acf112069aa3b6ba37d615ede758.tar.zst |
Add Profiler build for Android (#6510)
-rw-r--r-- | metro.config.js | 14 | ||||
-rw-r--r-- | package.json | 2 | ||||
-rw-r--r-- | src/App.native.tsx | 71 | ||||
-rw-r--r-- | src/AppProfiler.tsx | 29 |
4 files changed, 82 insertions, 34 deletions
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 ( - <GeolocationProvider> - <A11yProvider> - <KeyboardProvider enabled={false} statusBarTranslucent={true}> - <SessionProvider> - <PrefsStateProvider> - <I18nProvider> - <ShellStateProvider> - <InvitesStateProvider> - <ModalStateProvider> - <DialogStateProvider> - <LightboxStateProvider> - <PortalProvider> - <BottomSheetProvider> - <StarterPackProvider> - <SafeAreaProvider - initialMetrics={initialWindowMetrics}> - <IntentDialogProvider> - <InnerApp /> - </IntentDialogProvider> - </SafeAreaProvider> - </StarterPackProvider> - </BottomSheetProvider> - </PortalProvider> - </LightboxStateProvider> - </DialogStateProvider> - </ModalStateProvider> - </InvitesStateProvider> - </ShellStateProvider> - </I18nProvider> - </PrefsStateProvider> - </SessionProvider> - </KeyboardProvider> - </A11yProvider> - </GeolocationProvider> + <AppProfiler> + <GeolocationProvider> + <A11yProvider> + <KeyboardProvider enabled={false} statusBarTranslucent={true}> + <SessionProvider> + <PrefsStateProvider> + <I18nProvider> + <ShellStateProvider> + <InvitesStateProvider> + <ModalStateProvider> + <DialogStateProvider> + <LightboxStateProvider> + <PortalProvider> + <BottomSheetProvider> + <StarterPackProvider> + <SafeAreaProvider + initialMetrics={initialWindowMetrics}> + <IntentDialogProvider> + <InnerApp /> + </IntentDialogProvider> + </SafeAreaProvider> + </StarterPackProvider> + </BottomSheetProvider> + </PortalProvider> + </LightboxStateProvider> + </DialogStateProvider> + </ModalStateProvider> + </InvitesStateProvider> + </ShellStateProvider> + </I18nProvider> + </PrefsStateProvider> + </SessionProvider> + </KeyboardProvider> + </A11yProvider> + </GeolocationProvider> + </AppProfiler> ) } 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 = `<Profiler> ${id}:${phase} ${ + actualDuration > 500 + ? '(╯°□°)╯ ' + : actualDuration > 100 + ? '[!!] ' + : actualDuration > 16 + ? '[!] ' + : '' + }${Math.round(actualDuration)}ms` + log(message) + } +} + +export function AppProfiler({children}: {children: React.ReactNode}) { + return ( + <Profiler id="app" onRender={onRender}> + {children} + </Profiler> + ) +} |