RN中的系统日志

初始化流程:

介绍CxxBridge

CxxBridge是个对象,他拥有:

  • RCTModuleData(Array)这是moduleClass的对象和instance

  • RCTMessageThread 这里面封装了runAsync、runSync、runOnQueue等同步、异步、跨线程调用等方法。

  • Instance 这个是一个关键 loadJS、 native->js、 js->native 都是它

所以所初始化CxxBridge的时候,大概做了什么?

  • 把所有遵循了RCTBridgeModule协议的nativeModule都封装成RCTModuleData,另外js的所有变量及block也都被封装成nativeModule,怎么把js的东西初始化成这样的?
jscore->jscontext
  • 初始化一个NSThread 并且用NSThread的runtime初始化一个RCTMessageThread,用RCTMessageThread对象实现调用,怎么调用:
void RCTMessageThread::runAsync(std::function func) {
  CFRunLoopPerformBlock(m_cfRunLoop, kCFRunLoopCommonModes, ^{ func(); });
  CFRunLoopWakeUp(m_cfRunLoop);
}
  • 初始化Instance 用来初始化js代码、注册"RAM" bundle、js<->native,怎么调?
找到nativeModule就可以啦
屏幕快照 2019-04-10 下午5.53.30.png

下面是加载流程,代码开始也是在cxx的start方法中




如果不是RAMBundle,有可能是String、BCBundle比如我们的工程就是String,我们的资源包是

总结:初始化桥就是:创建js线程、下载js代码、通过js代码生成JSIExecutor、初始化nativeModule的总和

RCTPerformanceLogger(线上或者dev都存在)

markStartForTag和markStopForTag

mark:此日志 在DEV状态下也会存储于RCTProfileAddEvent中

如何存储

  • 调用- (void)markStopForTag:(RCTPLTag)tag 最终存储于_data中

都存储了那些、什么时候存储

存储了那些?

typedef NS_ENUM(NSUInteger, RCTPLTag) {
  RCTPLScriptDownload,
  RCTPLScriptExecution,
  RCTPLRAMBundleLoad,
  RCTPLRAMStartupCodeSize,
  RCTPLRAMStartupNativeRequires,
  RCTPLRAMStartupNativeRequiresCount,
  RCTPLRAMNativeRequires,
  RCTPLRAMNativeRequiresCount,
  RCTPLNativeModuleInit,
  RCTPLNativeModuleMainThread,
  RCTPLNativeModulePrepareConfig,
  RCTPLNativeModuleInjectConfig,
  RCTPLNativeModuleMainThreadUsesCount,
  RCTPLJSCWrapperOpenLibrary,
  RCTPLJSCExecutorSetup,
  RCTPLBridgeStartup,
  RCTPLTTI,
  RCTPLBundleSize,
  RCTPLSize
};

何时存储、存储数据类型、存储顺序 (CACurrentMediaTime() * 1000)

  • RCTPLScriptDownload,

mark:download jS资源
RCTPLScriptDownload_start(timestamp) order:11
RCTPLScriptDownload_end(timestamp) order:12

  • RCTPLScriptExecution,

mark:Download完成之后执行js时发出
RCTPLScriptExecution_start(timestamp) order:15
RCTPLScriptExecution_end(timestamp) order:16

  • RCTPLRAMBundleLoad,

mark:Download完成之后执行js时发出,比RCTPLScriptExecution早,但是只有当jssource是RAMBundle格式的时候才发
RCTPLRAMBundleLoad_start(timestamp) order:null
RCTPLRAMBundleLoad_end(timestamp) order:null

  • RCTPLRAMStartupCodeSize,

mark:RCTPLRAMBundleLoad之后发,也就是说同样jssource是RAMBundle格式的时候才发
RCTPLRAMBundleLoad_start(0) order:null
RCTPLRAMBundleLoad_end(int——size) order:null

  • RCTPLRAMStartupNativeRequires,

mark:未知
RCTPLRAMStartupNativeRequires_start(0) order:null
RCTPLRAMStartupNativeRequires_end(0) order:null

  • RCTPLRAMStartupNativeRequiresCount,

mark:未知
RCTPLRAMStartupNativeRequiresCount_start(0) order:null
RCTPLRAMStartupNativeRequiresCount_end(0) order:null

  • RCTPLRAMNativeRequires,

mark:未知
RCTPLRAMNativeRequirest_start(0) order:null
RCTPLRAMNativeRequires_end(0) order:null

  • RCTPLRAMNativeRequiresCount,

mark:未知
RCTPLRAMNativeRequiresCount_start(0) order:null
RCTPLRAMNativeRequiresCount_end(0) order:null

  • RCTPLNativeModuleInit,

mark:初始化NativeModule
RCTPLNativeModuleInit_start(timestamp) order:3
RCTPLNativeModuleInit_end(timestamp) order:10

  • RCTPLNativeModuleMainThread,

mark:主线程初始化NativeModule
RCTPLNativeModuleMainThread_start(0) order:4
RCTPLNativeModuleMainThread_end(timestamp差值n个在主线程初始化的Module时间和) order:5

  • RCTPLNativeModulePrepareConfig,

mark:为初始化NativeModule做准备,在初始化Instance的时候
RCTPLNativeModulePrepareConfig_start(timestamp) order:8
RCTPLNativeModulePrepareConfig_end(timestamp) order:9

  • RCTPLNativeModuleInjectConfig,

mark:未知
RCTPLNativeModuleInjectConfig_start(0) order:null
RCTPLNativeModuleInjectConfig_end(0) order:null

  • RCTPLNativeModuleMainThreadUsesCount,

mark:主线程初始化Module完成后统计在主线程初始化的Module的个数
RCTPLNativeModuleMainThreadUsesCount_start(0) order:6
RCTPLNativeModuleMainThreadUsesCount_end(int) order:7

  • RCTPLJSCWrapperOpenLibrary,

mark:未知
RCTPLJSCWrapperOpenLibrary_start(0) order:null
RCTPLJSCWrapperOpenLibrary_end(0) order:null

  • RCTPLJSCExecutorSetup,

mark:未知
RCTPLJSCExecutorSetup_start(0) order:null
RCTPLJSCExecutorSetup_end(0) order:null

  • RCTPLBridgeStartup,

mark:初始化桥,最最早的,一直到桥初始化结束
RCTPLBridgeStartup_start(timestamp) order:1
RCTPLBridgeStartup_end(timestamp) order:17

  • RCTPLTTI,

mark:从初始化桥到rootView被渲染出来
RCTPLTTI_start(timestamp) order:2(和RCTPLBridgeStartup_start一样)
RCTPLTTI_end(timestamp) order: 18

  • RCTPLBundleSize,

mark:记录下载下来的js的字符长度,下载结束之后就存起来了
RCTPLBundleSize_start(0) order:13
RCTPLBundleSize_end(int) order:14

  • RCTPLSize

mark:保留字段,目的是获取上面一共多少个日志

打开方式:QRN关闭了

RCTProfileAddEvent

以name为维度

  • "VSYNC"
RCTProfileDisplayLink = [CADisplayLink displayLinkWithTarget:[RCTProfile class]
                                                      selector:@selector(vsync:)];
  [RCTProfileDisplayLink addToRunLoop:[NSRunLoop mainRunLoop]
                              forMode:NSRunLoopCommonModes];

与屏幕帧率同步发出VSYNC,使用RCTProfileImmediateEvent记录时间戳,可用来检测屏幕卡顿。

  • "flow"

调用RCTProfileBeginFlowEvent、RCTProfileEndFlowEvent会添加,所以"flow"以两个一组的形式出现:他们有相同的id,ph的值(s标识Start f标识Finish)

{
        "name": "flow",
        "id": 129,
        "ts": 2959452.9999885708,
        "cat": "flow",
        "ph": "s",
        "tid": "com.facebook.react.JavaScript",
        "pid": 14689
    }, {
        "name": "flow",
        "id": 129,
        "ts": 2959476.8750248477,
        "cat": "flow",
        "ph": "f",
        "tid": "com.facebook.react.JavaScript",
        "pid": 14689
    }
> "flow"(调用流程)记录的时机如下:jscall 或者 callJSCallback 也或者 loadApplicationScript的时候RCTProfileBeginFlowEvent在放jsThread放入一个命令的时间戳、RCTProfileEndFlowEvent代表这个命令开始执行的时间戳,所以当这个间距时间长了,说明jsThread中有耗时操作,影响了其他任务的执行
  • "thread_sort_index"

固定5个分别是JS async(下载js资源)、RCTPerformanceLogger(com.facebook.react.Profiler 写日志的)、com.facebook.react.JavaScript (js线程)、com.facebook.react.ShadowQueue(RCTShadowView创建的地方)、main

{
      "ph" : "M",
      "tid" : "JS async",
      "args" : {
        "sort_index" : -1000
      },
      "name" : "thread_sort_index",
      "pid" : 14290
    },

args中的sort_index表示这5个线程id pid NSProcess的进程id

  • "RCTProfileHookModules"

只有一个,记录所有 modelHook打开的时间差,开启之后会产生js<-->native的调用链记录

  • JS Thread Tick

RCTDisplayLink 中CADisplayLink的轮训时间,使用RCTProfileImmediateEvent记录时间戳,可以通过来比对出js线程是否卡顿了

打开方式:rn->RCTDevSettings->setProfilingEnabled

你可能感兴趣的:(RN中的系统日志)