diff --git a/ReactCommon/react/renderer/components/text/ParagraphShadowNode.cpp b/ReactCommon/react/renderer/components/text/ParagraphShadowNode.cpp index 6b32654d891..0c485964273 100644 --- a/ReactCommon/react/renderer/components/text/ParagraphShadowNode.cpp +++ b/ReactCommon/react/renderer/components/text/ParagraphShadowNode.cpp @@ -14,7 +14,6 @@ #include #include #include -#include #include "ParagraphState.h" @@ -140,11 +139,6 @@ Size ParagraphShadowNode::measureContent( attributedString.appendFragment({string, textAttributes, {}}); } - auto telemetry = TransactionTelemetry::threadLocalTelemetry(); - if (telemetry) { - telemetry->didMeasureText(); - } - return textLayoutManager_ ->measure( AttributedStringBox{attributedString}, diff --git a/ReactCommon/react/renderer/mounting/TransactionTelemetry.cpp b/ReactCommon/react/renderer/mounting/TransactionTelemetry.cpp index 1f9afb44b27..1b0df9e3185 100644 --- a/ReactCommon/react/renderer/mounting/TransactionTelemetry.cpp +++ b/ReactCommon/react/renderer/mounting/TransactionTelemetry.cpp @@ -56,8 +56,18 @@ void TransactionTelemetry::willLayout() { layoutStartTime_ = telemetryTimePointNow(); } +void TransactionTelemetry::willMeasureText() { + react_native_assert( + lastTextMeasureStartTime_ == kTelemetryUndefinedTimePoint); + lastTextMeasureStartTime_ = telemetryTimePointNow(); +} + void TransactionTelemetry::didMeasureText() { numberOfTextMeasurements_++; + react_native_assert( + lastTextMeasureStartTime_ != kTelemetryUndefinedTimePoint); + textMeasureTime_ += telemetryTimePointNow() - lastTextMeasureStartTime_; + lastTextMeasureStartTime_ = kTelemetryUndefinedTimePoint; } void TransactionTelemetry::didLayout() { @@ -130,6 +140,10 @@ TelemetryTimePoint TransactionTelemetry::getMountEndTime() const { return mountEndTime_; } +TelemetryDuration TransactionTelemetry::getTextMeasureTime() const { + return textMeasureTime_; +} + int TransactionTelemetry::getNumberOfTextMeasurements() const { return numberOfTextMeasurements_; } diff --git a/ReactCommon/react/renderer/mounting/TransactionTelemetry.h b/ReactCommon/react/renderer/mounting/TransactionTelemetry.h index 88ef2a23b0e..6d06c2e59e7 100644 --- a/ReactCommon/react/renderer/mounting/TransactionTelemetry.h +++ b/ReactCommon/react/renderer/mounting/TransactionTelemetry.h @@ -36,6 +36,7 @@ class TransactionTelemetry final { void willCommit(); void didCommit(); void willLayout(); + void willMeasureText(); void didMeasureText(); void didLayout(); void willMount(); @@ -55,6 +56,7 @@ class TransactionTelemetry final { TelemetryTimePoint getMountStartTime() const; TelemetryTimePoint getMountEndTime() const; + TelemetryDuration getTextMeasureTime() const; int getNumberOfTextMeasurements() const; int getRevisionNumber() const; @@ -68,6 +70,9 @@ class TransactionTelemetry final { TelemetryTimePoint mountStartTime_{kTelemetryUndefinedTimePoint}; TelemetryTimePoint mountEndTime_{kTelemetryUndefinedTimePoint}; + TelemetryTimePoint lastTextMeasureStartTime_{kTelemetryUndefinedTimePoint}; + TelemetryDuration textMeasureTime_{0}; + int numberOfTextMeasurements_{0}; int revisionNumber_{0}; }; diff --git a/ReactCommon/react/renderer/mounting/tests/TransactionTelemetryTest.cpp b/ReactCommon/react/renderer/mounting/tests/TransactionTelemetryTest.cpp index 51e45944175..e8649f50ff7 100644 --- a/ReactCommon/react/renderer/mounting/tests/TransactionTelemetryTest.cpp +++ b/ReactCommon/react/renderer/mounting/tests/TransactionTelemetryTest.cpp @@ -49,8 +49,16 @@ TEST(TransactionTelemetryTest, normalUseCase) { telemetry.willLayout(); sleep(0.2); - telemetry.didMeasureText(); + TransactionTelemetry::threadLocalTelemetry()->willMeasureText(); + sleep(0.1); TransactionTelemetry::threadLocalTelemetry()->didMeasureText(); + + TransactionTelemetry::threadLocalTelemetry()->willMeasureText(); + sleep(0.2); + TransactionTelemetry::threadLocalTelemetry()->didMeasureText(); + + TransactionTelemetry::threadLocalTelemetry()->willMeasureText(); + sleep(0.3); TransactionTelemetry::threadLocalTelemetry()->didMeasureText(); telemetry.didLayout(); @@ -74,11 +82,15 @@ TEST(TransactionTelemetryTest, normalUseCase) { auto mountDuration = telemetryDurationToMilliseconds( telemetry.getMountEndTime() - telemetry.getMountStartTime()); - EXPECT_EQ_WITH_THRESHOLD(commitDuration, 400, threshold); - EXPECT_EQ_WITH_THRESHOLD(layoutDuration, 200, threshold); + EXPECT_EQ_WITH_THRESHOLD(commitDuration, 1000, threshold); + EXPECT_EQ_WITH_THRESHOLD(layoutDuration, 800, threshold); EXPECT_EQ_WITH_THRESHOLD(mountDuration, 100, threshold); EXPECT_EQ(telemetry.getNumberOfTextMeasurements(), 3); + EXPECT_EQ_WITH_THRESHOLD( + telemetryDurationToMilliseconds(telemetry.getTextMeasureTime()), + 600, + threshold); EXPECT_EQ(telemetry.getRevisionNumber(), 42); } diff --git a/ReactCommon/react/renderer/textlayoutmanager/Android.mk b/ReactCommon/react/renderer/textlayoutmanager/Android.mk index fd9e86cdb38..5af214a5ef7 100644 --- a/ReactCommon/react/renderer/textlayoutmanager/Android.mk +++ b/ReactCommon/react/renderer/textlayoutmanager/Android.mk @@ -11,7 +11,7 @@ LOCAL_MODULE := react_render_textlayoutmanager LOCAL_SRC_FILES := $(wildcard $(LOCAL_PATH)/*.cpp $(LOCAL_PATH)/platform/android/react/renderer/textlayoutmanager/*.cpp) -LOCAL_SHARED_LIBRARIES := libfolly_futures libreactnativeutilsjni libreact_utils libfb libfbjni libreact_render_uimanager libreact_render_componentregistry libreact_render_attributedstring libfolly_json libyoga libfolly_json libreact_render_core libreact_render_debug libreact_render_graphics libreact_debug +LOCAL_SHARED_LIBRARIES := libfolly_futures libreactnativeutilsjni libreact_utils libfb libfbjni libreact_render_uimanager libreact_render_componentregistry libreact_render_attributedstring libreact_render_mounting libfolly_json libyoga libfolly_json libreact_render_core libreact_render_debug libreact_render_graphics libreact_debug LOCAL_STATIC_LIBRARIES := @@ -34,6 +34,7 @@ $(call import-module,react/renderer/componentregistry) $(call import-module,react/renderer/core) $(call import-module,react/renderer/attributedstring) $(call import-module,react/renderer/debug) +$(call import-module,react/renderer/mounting) $(call import-module,react/renderer/graphics) $(call import-module,react/renderer/uimanager) $(call import-module,react/utils) diff --git a/ReactCommon/react/renderer/textlayoutmanager/BUCK b/ReactCommon/react/renderer/textlayoutmanager/BUCK index 8e2ac46c7d5..c79371156a8 100644 --- a/ReactCommon/react/renderer/textlayoutmanager/BUCK +++ b/ReactCommon/react/renderer/textlayoutmanager/BUCK @@ -129,6 +129,7 @@ rn_xplat_cxx_library( react_native_xplat_target("react/renderer/debug:debug"), react_native_xplat_target("react/renderer/graphics:graphics"), react_native_xplat_target("react/renderer/uimanager:uimanager"), + react_native_xplat_target("react/renderer/mounting:mounting"), react_native_xplat_target("react/renderer/componentregistry:componentregistry"), ], ) diff --git a/ReactCommon/react/renderer/textlayoutmanager/platform/android/react/renderer/textlayoutmanager/TextLayoutManager.cpp b/ReactCommon/react/renderer/textlayoutmanager/platform/android/react/renderer/textlayoutmanager/TextLayoutManager.cpp index a9e486219a3..04a21772bcf 100644 --- a/ReactCommon/react/renderer/textlayoutmanager/platform/android/react/renderer/textlayoutmanager/TextLayoutManager.cpp +++ b/ReactCommon/react/renderer/textlayoutmanager/platform/android/react/renderer/textlayoutmanager/TextLayoutManager.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include using namespace facebook::jni; @@ -34,8 +35,19 @@ TextMeasurement TextLayoutManager::measure( auto measurement = measureCache_.get( {attributedString, paragraphAttributes, layoutConstraints}, [&](TextMeasureCacheKey const &key) { - return doMeasure( - attributedString, paragraphAttributes, layoutConstraints); + auto telemetry = TransactionTelemetry::threadLocalTelemetry(); + if (telemetry) { + telemetry->willMeasureText(); + } + + auto measurement = + doMeasure(attributedString, paragraphAttributes, layoutConstraints); + + if (telemetry) { + telemetry->didMeasureText(); + } + + return measurement; }); measurement.size = layoutConstraints.clamp(measurement.size); diff --git a/ReactCommon/react/renderer/textlayoutmanager/platform/ios/TextLayoutManager.mm b/ReactCommon/react/renderer/textlayoutmanager/platform/ios/TextLayoutManager.mm index 881bcf90b47..1a877f50683 100644 --- a/ReactCommon/react/renderer/textlayoutmanager/platform/ios/TextLayoutManager.mm +++ b/ReactCommon/react/renderer/textlayoutmanager/platform/ios/TextLayoutManager.mm @@ -6,6 +6,7 @@ */ #include "TextLayoutManager.h" +#include #include #import "RCTTextLayoutManager.h" @@ -39,9 +40,20 @@ TextMeasurement TextLayoutManager::measure( measurement = measureCache_.get( {attributedString, paragraphAttributes, layoutConstraints}, [&](TextMeasureCacheKey const &key) { - return [textLayoutManager measureAttributedString:attributedString - paragraphAttributes:paragraphAttributes - layoutConstraints:layoutConstraints]; + auto telemetry = TransactionTelemetry::threadLocalTelemetry(); + if (telemetry) { + telemetry->willMeasureText(); + } + + auto measurement = [textLayoutManager measureAttributedString:attributedString + paragraphAttributes:paragraphAttributes + layoutConstraints:layoutConstraints]; + + if (telemetry) { + telemetry->didMeasureText(); + } + + return measurement; }); break; } @@ -50,9 +62,19 @@ TextMeasurement TextLayoutManager::measure( NSAttributedString *nsAttributedString = (NSAttributedString *)unwrapManagedObject(attributedStringBox.getOpaquePointer()); + auto telemetry = TransactionTelemetry::threadLocalTelemetry(); + if (telemetry) { + telemetry->willMeasureText(); + } + measurement = [textLayoutManager measureNSAttributedString:nsAttributedString paragraphAttributes:paragraphAttributes layoutConstraints:layoutConstraints]; + + if (telemetry) { + telemetry->didMeasureText(); + } + break; } }