Pre-UI Initialization Guide
Implementation patterns for the critical Pre-UI initialization stage in the application bootstrap process.
Pre-UI Initialization Guide
Overview
The Pre-UI initialization stage is the first and most critical phase of the application bootstrap process. During this phase, we perform essential setup tasks that must complete before showing any UI to the user.
Think of the Pre-UI stage as building the foundation for your application's user experience. The work done in this stage determines which screens users will see first, how the app will appear, and which core functionalities will be immediately available.
This guide explores practical implementation patterns to help you effectively manage the Pre-UI stage while maximizing performance – ensuring users see your app's interface as quickly as possible.
Quick Start
If you're eager to get started with Pre-UI initialization, here's a simplified approach you can implement right away:
-
Register your critical tasks with the initializer:
-
Keep the native splash screen visible until Pre-UI initialization completes:
-
Use the
useInitializationhook to track initialization progress in your components
The rest of this guide explains these concepts in depth, providing more context and advanced implementation patterns.
When To Use
The Pre-UI stage is best suited for a specific set of initialization tasks that must happen before your app can meaningfully display anything to the user. Let's explore which tasks belong in this stage and why careful consideration is important.
Appropriate Tasks for Pre-UI Initialization
-
Essential for Application Function: Components that must be available before any UI can be rendered
- Example: Reading authentication tokens to determine if a user is logged in
- Why: Without this, your app can't decide which screen to show first
-
Required for Navigation Decisions: Services that determine the initial navigation state
- Example: Checking if a user has completed onboarding
- Why: This information dictates the entire navigation flow of your app
-
Critical User Experience: Settings that significantly impact initial user experience
- Example: Loading theme preferences (light/dark) or language settings
- Why: Showing UI and then immediately changing these settings creates a jarring flash effect
Performance Considerations
Important: Keep Pre-UI initialization tasks to an absolute minimum, as every millisecond spent here directly adds to your app's startup time. Users often judge app quality based on startup performance, so this is a critical optimization area.
For tasks that are important but not critical to the first render, consider moving them to the initial-ui or background stages. This allows users to see and interact with your app sooner, improving perceived performance.
Implementation Patterns
Let's explore practical implementation patterns for the Pre-UI stage. Below is a visualization of how this stage fits into the overall app initialization flow:
As the diagram illustrates, the Pre-UI stage occurs immediately after app launch and before any UI is shown to the user. During this phase, we typically handle three primary concerns:
- Authentication State: Determining if a user is logged in
- Critical Preferences: Loading essential user settings
- App Configuration: Setting up core application parameters
Once these tasks complete, we transition from the native splash screen to the Initial UI rendering phase.
Splash Screen Management
For detailed implementation of splash screens during initialization, refer to the Splash Screen Guide. The Pre-UI initialization stage should integrate with splash screens as follows:
- Keep the native splash screen visible until Pre-UI initialization completes
- Use the splash screen's hide method as the final step of Pre-UI initialization
- Consider fade transitions for a smoother user experience
Here's a basic integration example using our abstracted SplashScreen component:
For complete implementation details, including setup, configuration, and advanced usage, see the Splash Screen Guide.
Authentication State Initialization
The most common Pre-UI initialization task is retrieving and validating authentication state. This information is crucial because it determines which UI flows your users will see - such as login screens, onboarding, or the main application content.
By loading authentication state during the Pre-UI stage, you can seamlessly route users to the appropriate screens during the initial-ui without jarring redirects or flashes of incorrect content.
Here's how you might implement authentication state initialization:
Critical Preferences Hydration
User preferences like theme choice (light/dark mode) and language settings directly affect how your UI appears. Loading these preferences during the Pre-UI stage helps prevent jarring visual changes after your app becomes visible.
Imagine a user with dark mode enabled seeing a bright white screen flash briefly before your app switches to dark mode—this creates a poor experience. By loading these critical preferences early, you ensure the UI appears correctly from the first moment.
Less critical preferences (like notification settings or display options) can be loaded later in the background. Here's how to implement critical preferences hydration:
App Configuration Loading
Load essential configuration that affects how the app should function:
Registering Multiple Pre-UI Tasks
When a domain requires multiple initialization tasks, use a centralized registration pattern:
Common Challenges
Managing Dependencies Between Tasks
Tasks in the Pre-UI stage often have dependencies on each other. Use the dependencies property to declare these relationships:
Handling Initialization Failures
Pre-UI tasks should be resilient to failures and provide fallbacks when possible:
Timeout Protection
Protect against hanging initialization tasks with timeout wrappers:
Performance Considerations
-
(Do ✅) Keep Pre-UI tasks minimal
- Only include absolutely critical initialization
- Consider moving tasks to later stages when possible
- Measure the impact of each task on startup time
-
(Do ✅) Use caching strategies
- Cache responses from previous sessions
- Use cache-first, update-in-background pattern
- Set appropriate cache expiration policies
-
(Don't ❌) Perform network requests unnecessarily
- Avoid network calls in Pre-UI stage if possible
- If required, set short timeouts (3-5 seconds)
- Always have offline fallbacks
-
(Do ✅) Load progressively
- Load only what's needed for initial UI
- Defer loading additional data to later stages
- Consider staged loading within the Pre-UI tasks themselves
Practical Examples
Application Theme Provider Initialization
Feature Flags Initialization
Migration Considerations
When migrating from older initialization patterns to our staged initialization approach for Pre-UI tasks, consider these helpful guidelines:
From Direct Initialization to Task-Based Approach
If you're currently using direct initialization in your app entry file like this:
You can enhance this by:
- Converting each initialization function to a task that follows the
InitTaskinterface - Registering these tasks with the initializer for the Pre-UI stage
- Using the centralizer initializer's flow management instead of custom state
This approach provides better error handling, performance tracking, and a clearer separation of concerns.
Ensuring Backward Compatibility
When implementing the new initialization system:
- Consider wrapping existing initialization logic in tasks temporarily during migration
- Keep fallbacks for essential functionality in case initialization fails
- Add detailed logging to help debug any issues during the transition
The task-based approach is particularly helpful for team development as it creates clear boundaries for initialization responsibilities.
Summary
The Pre-UI initialization stage forms the foundation of your app's startup experience. By thoughtfully implementing this stage, you'll significantly improve both actual and perceived performance for your users.
Key Takeaways
-
Strategic Task Placement: Be deliberate about what you include in the Pre-UI stage. Every task here directly impacts startup time.
-
User Experience Focus: The work done in this stage should enable a smooth, coherent experience from the moment the UI appears.
-
Staged Approach Benefits: By carefully dividing initialization between the Pre-UI stage and later stages like initial-ui, background, and finalization, you create a responsive app that feels fast even while work continues in the background.
Best Practices
- Keep Pre-UI tasks minimal and fast - Ruthlessly evaluate what truly needs to happen before showing UI
- Use caching aggressively - Store and reuse data to avoid network calls during startup
- Provide fallbacks for everything - Ensure your app can still function if initialization tasks fail
- Measure initialization performance - Use metrics to identify bottlenecks
- Move tasks to later stages whenever possible - If a task doesn't need to block UI rendering, defer it
By applying these patterns, you'll create a more responsive application that delights users with its speed and reliability.
Related Documents
Core Initialization Documentation
- App Initialization - Overview of the complete initialization architecture
- App Initialization Guides - Index of all initialization guides
Other Initialization Stages
- initial-ui - Next stage after Pre-UI completion
- background - Parallel tasks execution stage
- finalization - Final initialization stage
Related Implementation Guides
- Splash Screen Guide - Detailed implementation of splash screens during initialization
- Authentication Architecture - Authentication tokens and state management
- app-startup - Optimizing app startup performance