mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
232517a574
Summary: When experimenting with React Profiler API (https://reactjs.org/docs/profiler.html), I noticed that durations are integers without a debugger, but they are doubles with higher precision when debugger is attached. After digging into React Profiler code, I found out that it's using `performance.now()` to accumulate execution times of individual units of work. Since this method does not exist in React Native, it falls back to Javascript `Date`, leading to imprecise results. This PR introduces `global.nativePerformanceNow` function which returns precise native time, and a very basic `performance` polyfill with `now` function. This will greatly improve React Profiler API results, which is essential for profiling and benchmark tools. Solves https://github.com/facebook/react-native/issues/27274 ## Changelog [General] [Added] - Implement `nativePerformanceNow` and `performance.now()` Pull Request resolved: https://github.com/facebook/react-native/pull/27885 Test Plan: ``` const initialTime = global.performance.now(); setTimeout(() => { const newTime = global.performance.now(); console.warn('duration', newTime - initialTime); }, 1000); ``` ### Android + Hermes  ### Android + JSC  ### iOS  Reviewed By: ejanzer Differential Revision: D19888289 Pulled By: rickhanlonii fbshipit-source-id: ab8152382da9aee9b4b3c76f096e45d40f55da6c
45 lines
1.4 KiB
Plaintext
45 lines
1.4 KiB
Plaintext
/*
|
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*/
|
|
|
|
#include "JSCExecutorFactory.h"
|
|
|
|
#import <React/RCTLog.h>
|
|
#import <jsi/JSCRuntime.h>
|
|
|
|
#import <memory>
|
|
|
|
namespace facebook {
|
|
namespace react {
|
|
|
|
std::unique_ptr<JSExecutor> JSCExecutorFactory::createJSExecutor(
|
|
std::shared_ptr<ExecutorDelegate> delegate,
|
|
std::shared_ptr<MessageQueueThread> __unused jsQueue)
|
|
{
|
|
auto installBindings = [runtimeInstaller = runtimeInstaller_](jsi::Runtime &runtime) {
|
|
react::Logger iosLoggingBinder = [](const std::string &message, unsigned int logLevel) {
|
|
_RCTLogJavaScriptInternal(static_cast<RCTLogLevel>(logLevel), [NSString stringWithUTF8String:message.c_str()]);
|
|
};
|
|
react::bindNativeLogger(runtime, iosLoggingBinder);
|
|
|
|
react::PerformanceNow iosPerformanceNowBinder = []() {
|
|
// CACurrentMediaTime() returns the current absolute time, in seconds
|
|
return CACurrentMediaTime() * 1000;
|
|
};
|
|
react::bindNativePerformanceNow(runtime, iosPerformanceNowBinder);
|
|
|
|
// Wrap over the original runtimeInstaller
|
|
if (runtimeInstaller) {
|
|
runtimeInstaller(runtime);
|
|
}
|
|
};
|
|
return std::make_unique<JSIExecutor>(
|
|
facebook::jsc::makeJSCRuntime(), delegate, JSIExecutor::defaultTimeoutInvoker, std::move(installBindings));
|
|
}
|
|
|
|
} // namespace react
|
|
} // namespace facebook
|