Skip to content

Commit

Permalink
fix(ios): performance api of FP not working
Browse files Browse the repository at this point in the history
  • Loading branch information
wwwcg committed Jun 19, 2024
1 parent 473cf27 commit a63ddf3
Show file tree
Hide file tree
Showing 6 changed files with 131 additions and 56 deletions.
39 changes: 39 additions & 0 deletions framework/ios/base/bridge/HippyBridge+PerformanceAPI.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*!
* iOS SDK
*
* Tencent is pleased to support the open source community by making
* Hippy available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company.
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#import "HippyBridge.h"
#import "HippyBridge+PerformanceAPI.h"

NS_ASSUME_NONNULL_BEGIN

/// Performance API Category of HippyBridge
@interface HippyBridge (PerformanceAPI)

/// Update perf records of FP, DOM_START/DOM_END etc.
- (void)updatePerfRecordsOnRootContentDidAppear;

/// Update FCP perf record.
- (void)updatePerfRecordOnFirstContentfulPaintEnd;

@end

NS_ASSUME_NONNULL_END
64 changes: 64 additions & 0 deletions framework/ios/base/bridge/HippyBridge+PerformanceAPI.mm
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*!
* iOS SDK
*
* Tencent is pleased to support the open source community by making
* Hippy available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company.
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#import "HippyBridge+PerformanceAPI.h"
#import "HippyJSExecutor.h"
#import "driver/scope.h"

@implementation HippyBridge (PerformanceAPI)

- (void)updatePerfRecordsOnRootContentDidAppear {
std::shared_ptr<hippy::Scope> scope = self.javaScriptExecutor.pScope;
if (!scope) {
return;
}
auto domManager = scope->GetDomManager().lock();
auto performance = scope->GetPerformance();
if (domManager && performance) {
auto entry = performance->PerformanceNavigation(hippy::kPerfNavigationHippyInit);
if (!entry) {
return;
}
entry->SetHippyDomStart(domManager->GetDomStartTimePoint());
entry->SetHippyDomEnd(domManager->GetDomEndTimePoint());
entry->SetHippyFirstFrameStart(domManager->GetDomEndTimePoint());
entry->SetHippyFirstFrameEnd(footstone::TimePoint::SystemNow());
}
}

- (void)updatePerfRecordOnFirstContentfulPaintEnd {
std::shared_ptr<hippy::Scope> scope = self.javaScriptExecutor.pScope;
if (!scope) {
return;
}
auto domManager = scope->GetDomManager().lock();
auto performance = scope->GetPerformance();
if (domManager && performance) {
auto entry = performance->PerformanceNavigation(hippy::kPerfNavigationHippyInit);
if (!entry) {
return;
}
entry->SetHippyFirstContentfulPaintEnd(footstone::TimePoint::SystemNow());
}
}

@end
52 changes: 1 addition & 51 deletions framework/ios/base/bridge/HippyBridge.mm
Original file line number Diff line number Diff line change
Expand Up @@ -241,10 +241,7 @@ - (instancetype)initWithDelegate:(id<HippyBridgeDelegate>)delegate
_startTime = footstone::TimePoint::SystemNow();
HippyLogInfo(@"HippyBridge init begin, self:%p", self);
registerLogDelegateToHippyCore();
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(rootViewContentDidAppear:)
name:HippyContentDidAppearNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onFirstContentfulPaintEnd:)
name:HippyFirstContentfulPaintEndNotification object:nil];

HippyExecuteOnMainThread(^{
self->_isOSNightMode = [HippyDeviceBaseInfo isUIScreenInOSDarkMode];
self.cachedDimensionsInfo = hippyExportedDimensions(self);
Expand All @@ -267,53 +264,6 @@ - (instancetype)initWithDelegate:(id<HippyBridgeDelegate>)delegate
return self;
}

- (void)rootViewContentDidAppear:(NSNotification *)noti {
UIView *rootView = [noti object];
if (rootView) {
auto viewRenderManager = [rootView renderManager];
if (_renderManager && _renderManager == viewRenderManager.lock()) {
std::shared_ptr<hippy::Scope> scope = _javaScriptExecutor.pScope;
if (!scope) {
return;
}
auto domManager = scope->GetDomManager().lock();
auto performance = scope->GetPerformance();
if (domManager && performance) {
auto entry = performance->PerformanceNavigation(hippy::kPerfNavigationHippyInit);
if (!entry) {
return;
}
entry->SetHippyDomStart(domManager->GetDomStartTimePoint());
entry->SetHippyDomEnd(domManager->GetDomEndTimePoint());
entry->SetHippyFirstFrameStart(domManager->GetDomEndTimePoint());
entry->SetHippyFirstFrameEnd(footstone::TimePoint::SystemNow());
}
}
}
}

- (void)onFirstContentfulPaintEnd:(NSNotification *)noti {
UIView *fcpView = [noti object];
if (fcpView) {
auto viewRenderManager = [fcpView renderManager];
if (_renderManager && _renderManager == viewRenderManager.lock()) {
std::shared_ptr<hippy::Scope> scope = _javaScriptExecutor.pScope;
if (!scope) {
return;
}
auto domManager = scope->GetDomManager().lock();
auto performance = scope->GetPerformance();
if (domManager && performance) {
auto entry = performance->PerformanceNavigation(hippy::kPerfNavigationHippyInit);
if (!entry) {
return;
}
entry->SetHippyFirstContentfulPaintEnd(footstone::TimePoint::SystemNow());
}
}
}
}

- (void)dealloc {
/**
* This runs only on the main thread, but crashes the subclass
Expand Down
23 changes: 18 additions & 5 deletions renderer/native/ios/renderer/HippyRootView.mm
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#import "UIView+Hippy.h"
#import "HippyInvalidating.h"
#import "HippyBridge.h"
#import "Hippybridge+PerformanceAPI.h"
#import "HippyUIManager.h"
#import "HippyDeviceBaseInfo.h"
#import "HippyTouchHandler.h"
Expand All @@ -52,22 +53,34 @@

@interface HippyRootContentView : HippyView <HippyInvalidating>

/// Whether content has appeared
@property (nonatomic, readonly) BOOL contentHasAppeared;
/// The Touch handler of RootView
@property (nonatomic, strong) HippyTouchHandler *touchHandler;
/// timestamp of start
@property (nonatomic, assign) int64_t startTimpStamp;

/// Init Method
/// - Parameters:
/// - frame: frame
/// - bridge: hippy bridge
/// - hippyTag: root tag
/// - sizeFlexibility: size flexibility for auto resize
- (instancetype)initWithFrame:(CGRect)frame
bridge:(HippyBridge *)bridge
hippyTag:(NSNumber *)hippyTag
sizeFlexiblity:(HippyRootViewSizeFlexibility)sizeFlexibility NS_DESIGNATED_INITIALIZER;

@end
/// Unvaliable, use designated initializer.
- (instancetype)init NS_UNAVAILABLE;
/// Unvaliable, use designated initializer.
+ (instancetype)new NS_UNAVAILABLE;

@end

#pragma mark - HippyRootView

@interface HippyRootView () {
BOOL _contentHasAppeared;
BOOL _hasBusinessBundleToLoad;
}

Expand Down Expand Up @@ -409,17 +422,17 @@ - (void)hippySetFrame:(CGRect)frame {

- (void)insertHippySubview:(UIView *)subview atIndex:(NSInteger)atIndex {
[super insertHippySubview:subview atIndex:atIndex];
// [_bridge.performanceLogger markStopForTag:HippyPLTTI];

__weak __typeof(self)weakSelf = self;
dispatch_async(dispatch_get_main_queue(), ^{
__strong __typeof(weakSelf)strongSelf = weakSelf;
if (strongSelf && !strongSelf->_contentHasAppeared) {
strongSelf->_contentHasAppeared = YES;
// int64_t cost = [strongSelf.bridge.performanceLogger durationForTag:HippyPLTTI];
static NSString *const kHippyContentAppearCostKey = @"cost";
[[(HippyRootView *)strongSelf.superview bridge] updatePerfRecordsOnRootContentDidAppear];
[[NSNotificationCenter defaultCenter] postNotificationName:HippyContentDidAppearNotification
object:self.superview userInfo:@{
// @"cost": @(cost)
kHippyContentAppearCostKey : @(CACurrentMediaTime() * 1000 - strongSelf.startTimpStamp)
}];
}
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,13 @@ - (void)measureInAppWindow:(NSNumber *)componentTag
// Leave the implementation empty for now.
}

HIPPY_EXPORT_METHOD(removeFrameCallback:(nonnull NSNumber *)hippyTag
params:(NSDictionary *__nonnull)params
callback:(HippyPromiseResolveBlock)callback) {
// For devtools
// Leave the implementation empty for now.
}

#pragma mark - View properties

HIPPY_EXPORT_VIEW_PROPERTY(accessibilityLabel, NSString)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#import "objc/runtime.h"
#import "UIView+Hippy.h"
#import "HippyRootView.h"
#import "HippyBridge+PerformanceAPI.h"

/// The FCP Notification Imp
const NSNotificationName HippyFirstContentfulPaintEndNotification = @"HippyFirstContentfulPaintEndNotification";
Expand Down Expand Up @@ -127,6 +128,7 @@ @implementation HippyRootView (PaintEventSupport)
- (void)sendFCPNotiIfNeeded:(UIView *)fcpView {
if (nil == objc_getAssociatedObject(self, @selector(sendFCPNotiIfNeeded:))) {
objc_setAssociatedObject(self, @selector(sendFCPNotiIfNeeded:), @(YES), OBJC_ASSOCIATION_RETAIN);
[self.bridge updatePerfRecordOnFirstContentfulPaintEnd];
[NSNotificationCenter.defaultCenter postNotificationName:HippyFirstContentfulPaintEndNotification object:fcpView];
}
}
Expand Down

0 comments on commit a63ddf3

Please sign in to comment.