Is it a good practice to execute futures together at Initialization of the app OR should it be executed one at a time?

Viewed 185

Probably this is a noob question.

Suppose I have a Flutter code that has a few things to initialize at beginning before calling runApp. Consider this code:

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  /// Handles localizations
  final flutterI18nDelegate = FlutterI18nDelegate(
      translationLoader: FileTranslationLoader(
          fallbackFile: 'en_US',
          basePath: 'assets/i18n',
          forcedLocale: Locale('en_US'),
          decodeStrategies: [JsonDecodeStrategy()]));

  /// Handles AppsFlyer Integrations
  final AppsFlyerOptions appsFlyerOptions = AppsFlyerOptions(
    afDevKey: 'MY-KEY',
    appId: 'APP-ID',
    showDebug: true,
  );

  final appsFlyerSdk = AppsflyerSdk(appsFlyerOptions);

  /// Starts the Repository
  final repository = Repository();

  /// Initialize Mobile Ads
  final mobileAds = MobileAds.instance.initialize().then((InitializationStatus status) =>
      print('Mobile Ads Initialized! Status: ${status.adapterStatuses}'));

  final List<Future<dynamic>> initFutures = [
    /// Load Localizations
    flutterI18nDelegate.load(null),

    /// Initialize Firebase
    Firebase.initializeApp(),

    /// Initialize Repository
    repository.initialize(),

    /// Initialize AppsFlyer SDK
    appsFlyerSdk.initSdk(),

    /// Initialize Ads
    mobileAds,

    /// Initialize adaptiveMode (Dark, Light, System)
    AdaptiveTheme.getThemeMode()
  ];

  /// Run everything together to save time
  final initResults = await Future.wait(initFutures);
  final FlutterI18n flutterI18n = initResults.first;
  final AdaptiveThemeMode themeSetting = initResults.last ?? AdaptiveThemeMode.system;

  
  runApp(
    RestartWidget(
      child: MultiRepositoryProvider(
          providers: [
             /// ---- ALL Repository Needs ----
          ],
          child: MultiBlocProvider(
              providers: [
                  /// ---- ALL Bloc ----

              ],
              child: MyApp(
                flutterI18nDelegate: flutterI18nDelegate,
                themeSetting: themeSetting,
              ))),
    ),
  );
}


Notice that none of the futures being called depending on each other.

But is it a good practice to run futures like this in the start of the app?

Of course, the aim for executing futures together is to save time.

OR Is it better to do it like this:

/// Copying the futures part only 

  /// Load Localizations
  final FlutterI18n flutterI18n = await flutterI18nDelegate.load(null);

  /// Initialize Firebase
  await Firebase.initializeApp();

  /// Initialize Repository
  await repository.initialize();

  /// Initialize AppsFlyer SDK
  await appsFlyerSdk.initSdk();

  /// Initialize Ads
  await MobileAds.instance.initialize().then((InitializationStatus status) =>
      print('Mobile Ads Initialized! Status: ${status.adapterStatuses}'));

  /// Initialize adaptiveMode (Dark, Light, System)
  final AdaptiveThemeMode themeSetting = (await AdaptiveTheme.getThemeMode()) ?? AdaptiveThemeMode.system;

Please feel free to point out anything I probably miss or can be a concern for doing this or it is all good? and why? (e.g: memory leak concerns?)

Thanks

1 Answers

At first glance, I'd suggest not blocking app startup with a call like this:

final initResults = await Future.wait(initFutures);

The user will not know anything is happening and will just see a blank screen for however long it takes for all the futures & initialization to complete.

Using a FutureBuilder is perhaps the most common way to "wait" for async data to arrive, but also to show the user something while waiting.

I just answered a question with similar requirements (waiting for multiple, dependent sequential async data). Perhaps that will give you a rough idea of how to structure your app start up.

Related