From 82ca359df79b93243ae84ca8312b5b35555b3082 Mon Sep 17 00:00:00 2001 From: Linus Rath <139418639+rathlinus@users.noreply.github.com> Date: Thu, 24 Sep 2026 19:20:03 +0200 Subject: [PATCH] fix: stop loading the whole app for a background push `index.ts` imported `App` at the top, so when an FCM data message started the headless push task in a cold process, the bundle evaluated every screen, store, catalog and icon before the task could show its notification. The headless task is still registered at the top of `index.ts`, but the root component now requires `App` when the UI first renders. A headless start therefore only evaluates the task and its own imports; a normal launch evaluates the same modules as before, one render later. Measured with `npx expo export --platform android` (modules reached through top-level requires from the entry, i.e. what a headless start evaluates): 1,516 modules, 7,238 KB -> 202 modules, 745 KB. --- index.ts | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/index.ts b/index.ts index 891003c2..c68d2075 100644 --- a/index.ts +++ b/index.ts @@ -1,7 +1,7 @@ +import { createElement } from 'react'; import { AppRegistry } from 'react-native'; import { registerRootComponent } from 'expo'; -import App from './App'; import { pushBackgroundTask } from './src/lib/push-background-task'; // Runs in a fresh headless JS runtime when BulwarkPushTaskService is started @@ -9,7 +9,15 @@ import { pushBackgroundTask } from './src/lib/push-background-task'; // before the native service tries to invoke the task. AppRegistry.registerHeadlessTask('BulwarkPushTask', () => pushBackgroundTask); -// registerRootComponent calls AppRegistry.registerComponent('main', () => App); +// A headless push task evaluates this file too, so App is required when the +// UI first renders instead of imported above: importing it here would load +// every screen, store and icon before the task could run. +function Root() { + const App = (require('./App') as typeof import('./App')).default; + return createElement(App); +} + +// registerRootComponent calls AppRegistry.registerComponent('main', () => Root); // It also ensures that whether you load the app in Expo Go or in a native build, // the environment is set up appropriately -registerRootComponent(App); +registerRootComponent(Root);