How React Native eliminates startup whitescreen

Keywords: iOS github React

There is a short white screen after the start of RN project. The white screen takes a long time during debugging phase, about 3-5 seconds. The white screen time will be greatly shortened after playing a formal package. Most of the time is flashing, so it is called "flash".

In fact, there are many solutions, here is a simple summary.

Reasons for White Screen

In iOS App, there is LaunchImage, which will not appear until after the boot diagram is completed. This process is the process of JS interpretation. There is no content before the JS interpretation is completed, so the white screen is displayed. The solution is to do some simple processing after the boot diagram is completed and before the JS interpretation is completed.

Common solutions to:

  1. Load a full-screen placeholder picture with native code after the boot map is finished, which is the same as the boot map, to confuse "deceiving the user".
  2. Notify Native that the placeholder can be removed after the JS has been interpreted
  3. Receive notification from JS to remove a placeholder map

code implementation

Create a new SplashScreen file to receive the Remove Placeholder message from the JS.The code is as follows:
SplashScreen.h

#import <Foundation/Foundation.h>
  #import "RCTBridgeModule.h"
  @interface SplashScreen : NSObject<RCTBridgeModule>

  @end

SplashScreen.m

#import "SplashScreen.h"
  @implementation SplashScreen

  RCT_EXPORT_MODULE();

  RCT_EXPORT_METHOD(close){
    [[NSNotificationCenter defaultCenter] postNotificationName:@"Notification_CLOSE_SPLASH_SCREEN" object:nil];
  }
  @end

Add the following code to AppDelegate.m:

@interface AppDelegate ()
  {
    UIImageView *splashImage;
  }
  @end

  @implementation AppDelegate

  - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
  {
        [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(closeSplashImage) name:"Notification_CLOSE_SPLASH_SCREEN" object:nil];

      ...
      [self autoSplashScreen];//Write before return YES, after other code
      return YES;
  }
  -(void)autoSplashScreen {
    if (!splashImage) {
      splashImage = [[UIImageView alloc]initWithFrame:[UIScreen mainScreen].bounds];
    }
    if (IPHONESCREEN3p5) {
      [splashImage setImage:[UIImage imageNamed:@"launch4"]];
    }else if (IPHONESCREEN4){
      [splashImage setImage:[UIImage imageNamed:@"launch5"]];
    }else if (IPHONESCREEN4p7){
      [splashImage setImage:[UIImage imageNamed:@"launch6"]];
    }else if (IPHONESCREEN5p5){
      [splashImage setImage:[UIImage imageNamed:@"launch7"]];
    }
    [self.window addSubview:splashImage];
  }
  -(void)closeSplashImage {
        dispatch_sync(dispatch_get_main_queue(), ^{
          [UIView animateWithDuration:0.5 animations:^{
            splashImage.alpha = 0;
          } completion:^(BOOL finished){
            [splashImage removeFromSuperview];
          }];
        });
  }

Choose to remove the placeholder map at the appropriate time.js-side code:

if (Platform.OS === 'ios') {
      NativeModules.SplashScreen.close();
  };

More detailed information can be accessed: https://github.com/crazycodeboy/react-native-splash-screen/blob/master/README.zh.md

Posted by kybaker on Sat, 15 Jun 2019 09:45:21 -0700