mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Move timing definitions to a specific target (#45492)
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/45492 Changelog: [internal] When testing the changes in https://github.com/facebook/react-native/pull/45473 / D55491870, I saw that the reported time spans for long tasks didn't perfectly align with the long tasks themselves in traces (Perfetto). Taking a closer look, I realized that I wasn't doing the conversion between times and durations from `chrono` and `DOMHighResTimeStamp` (a `double`) correctly, and we're doing this conversion very often. This moves the definition of `DOMHighResTimeStamp` to its own library and adds conversion methods to make sure we don't make this mistake in the future. Reviewed By: rshest Differential Revision: D59820241 fbshipit-source-id: c123920de56336da384ddc484f6ac9d287724301
This commit is contained in:
committed by
Facebook GitHub Bot
parent
9aed45a9d9
commit
dffc156ea7
@@ -115,6 +115,7 @@ add_react_common_subdir(jserrorhandler)
|
||||
add_react_common_subdir(react/runtime)
|
||||
add_react_common_subdir(react/runtime/hermes)
|
||||
add_react_common_subdir(react/runtime/nativeviewconfig)
|
||||
add_react_common_subdir(react/timing)
|
||||
|
||||
# ReactAndroid JNI targets
|
||||
add_react_build_subdir(generated/source/codegen/jni)
|
||||
|
||||
@@ -28,4 +28,5 @@ target_link_libraries(react_cxxreact
|
||||
logger
|
||||
reactperflogger
|
||||
runtimeexecutor
|
||||
react_timing
|
||||
react_debug)
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <folly/Conv.h>
|
||||
#include <jsinspector-modern/ReactCdp.h>
|
||||
|
||||
#include <react/timing/primitives.h>
|
||||
#include <chrono>
|
||||
|
||||
namespace facebook::react {
|
||||
@@ -26,13 +27,7 @@ std::string JSExecutor::getSyntheticBundlePath(
|
||||
}
|
||||
|
||||
double JSExecutor::performanceNow() {
|
||||
auto time = std::chrono::steady_clock::now();
|
||||
auto duration = std::chrono::duration_cast<std::chrono::nanoseconds>(
|
||||
time.time_since_epoch())
|
||||
.count();
|
||||
|
||||
constexpr double NANOSECONDS_IN_MILLISECOND = 1000000.0;
|
||||
return duration / NANOSECONDS_IN_MILLISECOND;
|
||||
return chronoToDOMHighResTimeStamp(std::chrono::steady_clock::now());
|
||||
}
|
||||
|
||||
jsinspector_modern::RuntimeTargetDelegate&
|
||||
|
||||
@@ -52,6 +52,7 @@ Pod::Spec.new do |s|
|
||||
s.dependency "React-jsi", version
|
||||
s.dependency "React-logger", version
|
||||
s.dependency "React-debug", version
|
||||
s.dependency "React-timing", version
|
||||
|
||||
s.resource_bundles = {'React-cxxreact_privacy' => 'PrivacyInfo.xcprivacy'}
|
||||
|
||||
|
||||
@@ -19,4 +19,5 @@ add_library(react_performance_timeline SHARED ${react_performance_timeline_SRC})
|
||||
|
||||
target_include_directories(react_performance_timeline PUBLIC ${REACT_COMMON_DIR})
|
||||
target_link_libraries(react_performance_timeline
|
||||
react_timing
|
||||
react_cxxreact)
|
||||
|
||||
+1
-2
@@ -7,6 +7,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <react/timing/primitives.h>
|
||||
#include "BoundedConsumableBuffer.h"
|
||||
|
||||
#include <array>
|
||||
@@ -20,8 +21,6 @@
|
||||
|
||||
namespace facebook::react {
|
||||
|
||||
using DOMHighResTimeStamp = double;
|
||||
|
||||
using PerformanceEntryInteractionId = uint32_t;
|
||||
|
||||
enum class PerformanceEntryType {
|
||||
|
||||
+1
@@ -51,6 +51,7 @@ Pod::Spec.new do |s|
|
||||
s.header_mappings_dir = "../../.."
|
||||
end
|
||||
|
||||
s.dependency "React-timing"
|
||||
s.dependency "React-cxxreact"
|
||||
s.dependency "RCT-Folly", folly_version
|
||||
end
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
# Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
#
|
||||
# This source code is licensed under the MIT license found in the
|
||||
# LICENSE file in the root directory of this source tree.
|
||||
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
set(CMAKE_VERBOSE_MAKEFILE on)
|
||||
|
||||
add_compile_options(
|
||||
-fexceptions
|
||||
-frtti
|
||||
-std=c++20
|
||||
-Wall
|
||||
-Wpedantic)
|
||||
|
||||
add_library(react_timing INTERFACE)
|
||||
|
||||
target_include_directories(react_timing INTERFACE .)
|
||||
@@ -0,0 +1,44 @@
|
||||
# Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
#
|
||||
# This source code is licensed under the MIT license found in the
|
||||
# LICENSE file in the root directory of this source tree.
|
||||
|
||||
require "json"
|
||||
|
||||
package = JSON.parse(File.read(File.join(__dir__, "..", "..", "..", "package.json")))
|
||||
version = package['version']
|
||||
|
||||
source = { :git => 'https://github.com/facebook/react-native.git' }
|
||||
if version == '1000.0.0'
|
||||
# This is an unpublished version, use the latest commit hash of the react-native repo, which we’re presumably in.
|
||||
source[:commit] = `git rev-parse HEAD`.strip if system("git rev-parse --git-dir > /dev/null 2>&1")
|
||||
else
|
||||
source[:tag] = "v#{version}"
|
||||
end
|
||||
|
||||
header_search_paths = []
|
||||
|
||||
if ENV['USE_FRAMEWORKS']
|
||||
header_search_paths << "\"$(PODS_TARGET_SRCROOT)/../..\"" # this is needed to allow the target access its own files
|
||||
end
|
||||
|
||||
Pod::Spec.new do |s|
|
||||
s.name = "React-timing"
|
||||
s.version = version
|
||||
s.summary = "React Native timing primitives"
|
||||
s.homepage = "https://reactnative.dev/"
|
||||
s.license = package["license"]
|
||||
s.author = "Meta Platforms, Inc. and its affiliates"
|
||||
s.platforms = min_supported_versions
|
||||
s.source = source
|
||||
s.source_files = "*.{cpp,h}"
|
||||
s.header_dir = "react/timing"
|
||||
s.pod_target_xcconfig = { "CLANG_CXX_LANGUAGE_STANDARD" => rct_cxx_language_standard(),
|
||||
"HEADER_SEARCH_PATHS" => header_search_paths.join(' '),
|
||||
"DEFINES_MODULE" => "YES" }
|
||||
|
||||
if ENV['USE_FRAMEWORKS']
|
||||
s.module_name = "React_timing"
|
||||
s.header_mappings_dir = "./"
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <chrono>
|
||||
|
||||
namespace facebook::react {
|
||||
|
||||
// `DOMHighResTimeStamp` represents a time value in milliseconds (time point or
|
||||
// duration), with sub-millisecond precision.
|
||||
// On the Web, the precision can be reduced for security purposes, but that is
|
||||
// not necessary in React Native.
|
||||
using DOMHighResTimeStamp = double;
|
||||
|
||||
inline DOMHighResTimeStamp chronoToDOMHighResTimeStamp(
|
||||
std::chrono::steady_clock::duration duration) {
|
||||
return static_cast<std::chrono::duration<double, std::milli>>(duration)
|
||||
.count();
|
||||
}
|
||||
|
||||
inline DOMHighResTimeStamp chronoToDOMHighResTimeStamp(
|
||||
std::chrono::steady_clock::time_point timePoint) {
|
||||
return chronoToDOMHighResTimeStamp(timePoint.time_since_epoch());
|
||||
}
|
||||
|
||||
} // namespace facebook::react
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "../primitives.h"
|
||||
|
||||
namespace facebook::react {
|
||||
|
||||
using Clock = std::chrono::steady_clock;
|
||||
using TimePoint = std::chrono::time_point<Clock>;
|
||||
|
||||
TEST(chronoToDOMHighResTimeStamp, withDurations) {
|
||||
EXPECT_EQ(chronoToDOMHighResTimeStamp(std::chrono::nanoseconds(10)), 0.00001);
|
||||
EXPECT_EQ(chronoToDOMHighResTimeStamp(std::chrono::microseconds(10)), 0.01);
|
||||
EXPECT_EQ(chronoToDOMHighResTimeStamp(std::chrono::milliseconds(10)), 10.0);
|
||||
EXPECT_EQ(chronoToDOMHighResTimeStamp(std::chrono::seconds(10)), 10000.0);
|
||||
EXPECT_EQ(
|
||||
chronoToDOMHighResTimeStamp(
|
||||
std::chrono::seconds(1) + std::chrono::nanoseconds(20)),
|
||||
1000.000020);
|
||||
}
|
||||
|
||||
TEST(chronoToDOMHighResTimeStamp, withTimePoints) {
|
||||
EXPECT_EQ(
|
||||
chronoToDOMHighResTimeStamp(TimePoint(std::chrono::nanoseconds(10))),
|
||||
0.00001);
|
||||
EXPECT_EQ(
|
||||
chronoToDOMHighResTimeStamp(TimePoint(std::chrono::microseconds(10))),
|
||||
0.01);
|
||||
EXPECT_EQ(
|
||||
chronoToDOMHighResTimeStamp(TimePoint(std::chrono::milliseconds(10))),
|
||||
10.0);
|
||||
EXPECT_EQ(
|
||||
chronoToDOMHighResTimeStamp(TimePoint(std::chrono::seconds(10))),
|
||||
10000.0);
|
||||
EXPECT_EQ(
|
||||
chronoToDOMHighResTimeStamp(
|
||||
TimePoint(std::chrono::seconds(1) + std::chrono::nanoseconds(20))),
|
||||
1000.000020);
|
||||
}
|
||||
|
||||
} // namespace facebook::react
|
||||
@@ -630,6 +630,7 @@ class ReactNativePodsUtils
|
||||
"React-perflogger",
|
||||
"React-rncore",
|
||||
"React-runtimeexecutor",
|
||||
"React-timing",
|
||||
"ReactCommon",
|
||||
"Yoga",
|
||||
"boost",
|
||||
|
||||
@@ -142,6 +142,7 @@ def use_react_native! (
|
||||
|
||||
pod 'React-callinvoker', :path => "#{prefix}/ReactCommon/callinvoker"
|
||||
pod 'React-performancetimeline', :path => "#{prefix}/ReactCommon/react/performance/timeline"
|
||||
pod 'React-timing', :path => "#{prefix}/ReactCommon/react/timing"
|
||||
pod 'React-runtimeexecutor', :path => "#{prefix}/ReactCommon/runtimeexecutor"
|
||||
pod 'React-runtimescheduler', :path => "#{prefix}/ReactCommon/react/renderer/runtimescheduler"
|
||||
pod 'React-rendererdebug', :path => "#{prefix}/ReactCommon/react/renderer/debug"
|
||||
|
||||
Reference in New Issue
Block a user