Permalink
Browse files

Introduce Perf Monitor

Summary: public

Kill `RCTPerfStats` and introduce the new `RCTPerfMonitor`, including memory
usage, JSC heap size, number of RN views in screen, FPS (both on UI and JS threads)
and more to come.

It removes all the previous traces that were previous spread across the bridge
and the dev menu and moves everything to be more contained, so the whole thing
can be safely striped in production.

Reviewed By: nicklockwood

Differential Revision: D2575158

fb-gh-sync-id: 6a6d0c4422adbddeeefddd32ec3409a7095ff2a9
  • Loading branch information...
tadeuzagallo authored and facebook-github-bot-7 committed Oct 23, 2015
1 parent cae4761 commit 9069bdf1c2e4ffd78b634d015b32dfec2cd3a371
@@ -20,7 +20,6 @@
#import "RCTModuleMap.h"
#import "RCTBridgeMethod.h"
#import "RCTPerformanceLogger.h"
-#import "RCTPerfStats.h"
#import "RCTProfile.h"
#import "RCTRedBox.h"
#import "RCTSourceCode.h"
@@ -68,7 +67,6 @@ @implementation RCTBatchedBridge
NSMutableArray *_pendingCalls;
NSMutableArray *_moduleDataByID;
RCTModuleMap *_modulesByName;
- CADisplayLink *_mainDisplayLink;
CADisplayLink *_jsDisplayLink;
NSMutableSet *_frameUpdateObservers;
}
@@ -94,11 +92,6 @@ - (instancetype)initWithParentBridge:(RCTBridge *)bridge
_frameUpdateObservers = [NSMutableSet new];
_jsDisplayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(_jsThreadUpdate:)];
- if (RCT_DEV) {
- _mainDisplayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(_mainThreadUpdate:)];
- [_mainDisplayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
- }
-
[RCTBridge setCurrentBridge:self];
[[NSNotificationCenter defaultCenter] postNotificationName:RCTJavaScriptWillStartLoadingNotification
@@ -508,9 +501,6 @@ - (void)invalidate
[RCTBridge setCurrentBridge:nil];
}
- [_mainDisplayLink invalidate];
- _mainDisplayLink = nil;
-
// Invalidate modules
dispatch_group_t group = dispatch_group_create();
for (RCTModuleData *moduleData in _moduleDataByID) {
@@ -868,21 +858,6 @@ - (void)_jsThreadUpdate:(CADisplayLink *)displayLink
RCTProfileImmediateEvent(0, @"JS Thread Tick", 'g');
RCTProfileEndEvent(0, @"objc_call", nil);
-
- RCT_IF_DEV(
- dispatch_async(dispatch_get_main_queue(), ^{
- [self.perfStats.jsGraph onTick:displayLink.timestamp];
- });
- )
-}
-
-- (void)_mainThreadUpdate:(CADisplayLink *)displayLink
-{
- RCTAssertMainThread();
-
- RCTProfileImmediateEvent(0, @"VSYNC", 'g');
-
- _modulesByName == nil ?: [self.perfStats.uiGraph onTick:displayLink.timestamp];
}
- (void)startProfiling
View
@@ -1,138 +0,0 @@
-/**
- * Copyright (c) 2015-present, Facebook, Inc.
- * All rights reserved.
- *
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
- */
-
-#import "RCTFPSGraph.h"
-
-#import "RCTAssert.h"
-#import "RCTDefines.h"
-
-#if RCT_DEV
-
-@implementation RCTFPSGraph
-{
- CAShapeLayer *_graph;
- NSString *_name;
- NSTimeInterval _prevTime;
- RCTFPSGraphPosition _position;
- UILabel *_label;
-
- float *_frames;
- int _frameCount;
- int _maxFPS;
- int _minFPS;
- int _length;
- int _margin;
- int _height;
-}
-
-- (instancetype)initWithFrame:(CGRect)frame graphPosition:(RCTFPSGraphPosition)position name:(NSString *)name color:(UIColor *)color
-{
- if ((self = [super initWithFrame:frame])) {
- _margin = 2;
- _prevTime = -1;
- _maxFPS = 0;
- _minFPS = 60;
- _length = (frame.size.width - 2 * _margin) / 2;
- _height = frame.size.height - 2 * _margin;
- _frames = malloc(sizeof(float) * _length);
- memset(_frames, 0, sizeof(float) * _length);
-
- _name = name ?: @"FPS";
- _position = position ?: RCTFPSGraphPositionLeft;
-
- color = color ?: [UIColor greenColor];
- _graph = [self createGraph:color];
- _label = [self createLabel:color];
-
- [self addSubview:_label];
- [self.layer addSublayer:_graph];
- }
- return self;
-}
-
-RCT_NOT_IMPLEMENTED(- (instancetype)initWithFrame:(CGRect)frame)
-RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)aDecoder)
-
-- (void)dealloc
-{
- free(_frames);
-}
-
-- (void)layoutSubviews
-{
- [super layoutSubviews];
-}
-
-- (CAShapeLayer *)createGraph:(UIColor *)color
-{
- CGFloat left = _position & RCTFPSGraphPositionLeft ? 0 : _length;
- CAShapeLayer *graph = [CAShapeLayer new];
- graph.frame = CGRectMake(left, 0, 2 * _margin + _length, self.frame.size.height);
- graph.backgroundColor = [color colorWithAlphaComponent:0.2].CGColor;
- graph.fillColor = color.CGColor;
- return graph;
-}
-
-- (UILabel *)createLabel:(UIColor *)color
-{
- CGFloat left = _position & RCTFPSGraphPositionLeft ? 2 * _margin + _length : 0;
- UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(left, 0, _length, self.frame.size.height)];
- label.textColor = color;
- label.font = [UIFont systemFontOfSize:9];
- label.minimumScaleFactor = .5;
- label.adjustsFontSizeToFitWidth = YES;
- label.numberOfLines = 3;
- label.lineBreakMode = NSLineBreakByWordWrapping;
- label.textAlignment = NSTextAlignmentCenter;
- return label;
-}
-
-- (void)onTick:(NSTimeInterval)timestamp
-{
- _frameCount++;
- if (_prevTime == -1) {
- _prevTime = timestamp;
- } else if (timestamp - _prevTime > 1) {
- float fps = round(_frameCount / (timestamp - _prevTime));
- _minFPS = MIN(_minFPS, fps);
- _maxFPS = MAX(_maxFPS, fps);
-
- _label.text = [NSString stringWithFormat:@"%@\n%d FPS\n(%d - %d)", _name, (int)fps, _minFPS, _maxFPS];
-
- float scale = 60.0 / _height;
- for (int i = 0; i < _length - 1; i++) {
- _frames[i] = _frames[i + 1];
- }
- _frames[_length - 1] = fps / scale;
-
- CGMutablePathRef path = CGPathCreateMutable();
- if (_position & RCTFPSGraphPositionLeft) {
- CGPathMoveToPoint(path, NULL, _margin, _margin + _height);
- for (int i = 0; i < _length; i++) {
- CGPathAddLineToPoint(path, NULL, _margin + i, _margin + _height - _frames[i]);
- }
- CGPathAddLineToPoint(path, NULL, _margin + _length - 1, _margin + _height);
- } else {
- CGPathMoveToPoint(path, NULL, _margin + _length - 1, _margin + _height);
- for (int i = 0; i < _length; i++) {
- CGPathAddLineToPoint(path, NULL, _margin + _length - i - 1, _margin + _height - _frames[i]);
- }
- CGPathAddLineToPoint(path, NULL, _margin, _margin + _height);
- }
- _graph.path = path;
- CGPathRelease(path);
-
- _prevTime = timestamp;
- _frameCount = 0;
- }
-}
-
-@end
-
-#endif
View
@@ -1,27 +0,0 @@
-/**
- * Copyright (c) 2015-present, Facebook, Inc.
- * All rights reserved.
- *
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
- */
-
-#import "RCTBridge.h"
-#import "RCTFPSGraph.h"
-
-@interface RCTPerfStats : NSObject
-
-@property (nonatomic, strong) RCTFPSGraph *jsGraph;
-@property (nonatomic, strong) RCTFPSGraph *uiGraph;
-
-- (void)show;
-- (void)hide;
-
-@end
-
-@interface RCTBridge (RCTPerfStats)
-
-@property (nonatomic, strong, readonly) RCTPerfStats *perfStats;
-
-@end
View
@@ -1,147 +0,0 @@
-/**
- * Copyright (c) 2015-present, Facebook, Inc.
- * All rights reserved.
- *
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
- */
-
-#import "RCTPerfStats.h"
-
-#import "RCTDefines.h"
-#import "RCTUtils.h"
-
-#if RCT_DEV
-
-@interface RCTPerfStats() <RCTBridgeModule>
-
-@end
-
-@implementation RCTPerfStats
-{
- UIView *_container;
-}
-
-RCT_EXPORT_MODULE()
-
-- (void)dealloc
-{
- [self hide];
-}
-
-- (UIView *)container
-{
- if (!_container) {
- _container = [UIView new];
- _container.backgroundColor = [UIColor colorWithRed:0 green:0 blue:34/255.0 alpha:1];
- _container.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleWidth;
- }
- return _container;
-}
-
-- (RCTFPSGraph *)jsGraph
-{
- if (!_jsGraph && _container) {
- UIColor *jsColor = [UIColor colorWithRed:0 green:1 blue:0 alpha:1];
- _jsGraph = [[RCTFPSGraph alloc] initWithFrame:CGRectMake(2, 2, 124, 34)
- graphPosition:RCTFPSGraphPositionRight
- name:@"[ JS ]"
- color:jsColor];
- _jsGraph.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin;
- }
- return _jsGraph;
-}
-
-- (RCTFPSGraph *)uiGraph
-{
- if (!_uiGraph && _container) {
- UIColor *uiColor = [UIColor colorWithRed:0 green:1 blue:1 alpha:1];
- _uiGraph = [[RCTFPSGraph alloc] initWithFrame:CGRectMake(2, 2, 124, 34)
- graphPosition:RCTFPSGraphPositionLeft
- name:@"[ UI ]"
- color:uiColor];
- }
- return _uiGraph;
-}
-
-- (void)show
-{
- if (RCTRunningInAppExtension()) {
- return;
- }
-
- UIView *targetView = RCTSharedApplication().delegate.window.rootViewController.view;
-
- targetView.frame = (CGRect){
- targetView.frame.origin,
- {
- targetView.frame.size.width,
- targetView.frame.size.height - 38,
- }
- };
-
- self.container.frame = (CGRect){{0, targetView.frame.size.height}, {targetView.frame.size.width, 38}};
- self.jsGraph.frame = (CGRect){
- {
- targetView.frame.size.width - self.uiGraph.frame.size.width - self.uiGraph.frame.origin.x,
- self.uiGraph.frame.origin.x,
- },
- self.uiGraph.frame.size,
- };
-
- [self.container addSubview:self.jsGraph];
- [self.container addSubview:self.uiGraph];
- [targetView addSubview:self.container];
-}
-
-- (void)hide
-{
- UIView *targetView = _container.superview;
-
- targetView.frame = (CGRect){
- targetView.frame.origin,
- {
- targetView.frame.size.width,
- targetView.frame.size.height + _container.frame.size.height
- }
- };
-
- [_container removeFromSuperview];
-}
-
-- (dispatch_queue_t)methodQueue
-{
- return dispatch_get_main_queue();
-}
-
-@end
-
-@implementation RCTBridge (RCTPerfStats)
-
-- (RCTPerfStats *)perfStats
-{
- return self.modules[RCTBridgeModuleNameForClass([RCTPerfStats class])];
-}
-
-@end
-
-#else
-
-@implementation RCTPerfStats
-
-- (void)show {}
-- (void)hide {}
-
-@end
-
-@implementation RCTBridge (RCTPerfStats)
-
-- (RCTPerfStats *)perfStats
-{
- return nil;
-}
-
-@end
-
-#endif
Oops, something went wrong.

0 comments on commit 9069bdf

Please sign in to comment.