iOS 实现react-native预加载,优化第一次加载白屏问题

项目中存在多个react-native页面入口,每个入口使用以下方法初始化:

- (instancetype)initWithBundleURL:(NSURL *)bundleURL
                       moduleName:(NSString *)moduleName
                initialProperties:(NSDictionary *)initialProperties
                    launchOptions:(NSDictionary *)launchOptions;

但在调试中发现两个现象:
1.重复进入react-native页面、退出react-native页面的操作,RCTBridge对象会被重复创建、销毁。有时候RCTBridge对象未能及时创建还会crash
2.在原生页面和react-native页面相互跳转是RCTBridge也会被重复创建,造成很大的内存开销

带着疑问去阅读RCTRootView.h发现一些细节:

/**
 * - Designated initializer -
 */
- (instancetype)initWithBridge:(RCTBridge *)bridge
                    moduleName:(NSString *)moduleName
             initialProperties:(NSDictionary *)initialProperties NS_DESIGNATED_INITIALIZER;

/**
 * - Convenience initializer -
 * A bridge will be created internally.
 * This initializer is intended to be used when the app has a single RCTRootView,
 * otherwise create an `RCTBridge` and pass it in via `initWithBridge:moduleName:`
 * to all the instances.
 */
- (instancetype)initWithBundleURL:(NSURL *)bundleURL
                       moduleName:(NSString *)moduleName
                initialProperties:(NSDictionary *)initialProperties
                    launchOptions:(NSDictionary *)launchOptions;

可以看到项目中使用多个RCTRootView时,推荐使用以下方法初始化:

- (instancetype)initWithBridge:(RCTBridge *)bridge
                    moduleName:(NSString *)moduleName
             initialProperties:(NSDictionary *)initialProperties NS_DESIGNATED_INITIALIZER;

通过上述的两个现象和推荐的初始化API,很自然的可以想到使用单例初始化一个bridge对象解决上述问题:

//.h
@interface BridgeManager: RCTBridge

+ (BridgeManager*)shareInstance;
@end

@interface BridgeHandle : NSObject<RCTBridgeDelegate>

@end

//.m
implementation MallBridgeHandle

- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
{
    return [[NSBundle mainBundle] URLForResource:@"index.ios" withExtension:@"jsbundle"];  
}
@end

@implementation BridgeManager
static BridgeManager * manager = nil;
static dispatch_once_t onceToken;
+ (BridgeManager*)shareInstance
{
    dispatch_once(&onceToken,^{
        manager = [BridgeManager alloc] initWithDelegate:[[BridgeHandle alloc] init] launchOptions:nil]; 
    });
    return manager ;
}
@end

单例在程序启动时初始化。
测试验证可以发现:内存得到优化,白屏问题得到解决。

你可能感兴趣的:(react-native,iOS,白屏优化,内存优化)