iOS: Warn about slow main thread React methods

Summary:
When code blocks the UI thread for too long, it's a bad sign because this can prevent the app from remaining responsive. This change helps detect such responsiveness issues by warning when a React method executes on the UI thread longer than some threshold.

**Test Plan**

Changed AppState's getCurrentAppState method to sleep for 500 ms and verified that a warning was emitted:

```
2017-08-17 19:45:29.479 [warn][tid:main][RCTModuleMethod.mm:527] mainThreadWatchdog: invocation of [RCTAppState getCurrentAppState:error:] took 501ms
```

Adam Comella
Microsoft Corp.
Closes https://github.com/facebook/react-native/pull/15542

Differential Revision: D5724764

Pulled By: shergin

fbshipit-source-id: f1dc4bf17d3657c397720a47fabc7f32bf81b7ac
This commit is contained in:
Adam Comella 2017-08-28 22:37:51 -07:00 committed by Facebook Github Bot
parent 94a2ff93db
commit 68461492bc
1 changed files with 19 additions and 0 deletions

View File

@ -22,6 +22,10 @@
#import "RCTProfile.h"
#import "RCTUtils.h"
#if !defined(RCT_MAIN_THREAD_WATCH_DOG_THRESHOLD) && defined(RCT_DEBUG)
#define RCT_MAIN_THREAD_WATCH_DOG_THRESHOLD 0.020 // seconds
#endif
typedef BOOL (^RCTArgumentBlock)(RCTBridge *, NSUInteger, id);
@implementation RCTMethodArgument
@ -516,7 +520,22 @@ RCT_EXTERN_C_END
}
// Invoke method
#ifdef RCT_MAIN_THREAD_WATCH_DOG_THRESHOLD
if (RCTIsMainQueue()) {
CFTimeInterval start = CACurrentMediaTime();
[_invocation invokeWithTarget:module];
CFTimeInterval duration = CACurrentMediaTime() - start;
if (duration > RCT_MAIN_THREAD_WATCH_DOG_THRESHOLD) {
RCTLogWarn(@"mainThreadWatchdog: invocation of %@ blocked the main thread for %dms. Consider spending less time on the main thread to keep the app's UI responsive.",
[self methodName],
(int)(duration * 1000));
}
} else {
[_invocation invokeWithTarget:module];
}
#else
[_invocation invokeWithTarget:module];
#endif
index = 2;
[_retainedObjects removeAllObjects];