Skip to content

The clock used for performance.now() is not monotonic #33977

@opayen

Description

@opayen

Description

In React Native 0.68, the Performance.now() implementation changed to use unix epoch timestamps instead of a monotonic clock in #32695 (both on iOS and Android).

This is problematic, because it means that performance measurements get skewed if the device clock changes between two measurements.

Version

0.68.0

Output of npx react-native info

System:
OS: macOS 12.3.1
CPU: (10) x64 Apple M1 Pro
Memory: 60.86 MB / 32.00 GB
Shell: 5.8 - /bin/zsh
Binaries:
Node: 14.18.2 - ~/.volta/tools/image/node/14.18.2/bin/node
Yarn: 1.22.18 - /opt/homebrew/bin/yarn
npm: 6.14.15 - ~/.volta/tools/image/node/14.18.2/bin/npm
Watchman: 2022.05.16.00 - /opt/homebrew/bin/watchman
Managers:
CocoaPods: 1.11.3 - /Users/olivier.payen/.asdf/shims/pod
SDKs:
iOS SDK:
Platforms: DriverKit 21.4, iOS 15.5, macOS 12.3, tvOS 15.4, watchOS 8.5
Android SDK:
API Levels: 29, 30, 31, 32
Build Tools: 28.0.3, 29.0.2, 30.0.2, 30.0.3, 31.0.0, 32.0.0, 32.1.0
System Images: android-30 | Intel x86 Atom_64, android-30 | Google APIs ARM 64 v8a, android-30 | Google APIs Intel x86 Atom_64, android-30 | Google Play ARM 64 v8a, android-31 | Google Play ARM 64 v8a, android-32 | Google APIs ARM 64 v8a, android-Tiramisu | Google Play ARM 64 v8a
Android NDK: Not Found
IDEs:
Android Studio: 2021.2 AI-212.5712.43.2112.8512546
Xcode: 13.4.1/13F100 - /usr/bin/xcodebuild
Languages:
Java: 11.0.12 - /Applications/Android Studio.app/Contents/jre/Contents/Home/bin/javac
npmPackages:
@react-native-community/cli: Not Found
react: 17.0.2 => 17.0.2
react-native: 0.68.0 => 0.68.0
react-native-macos: Not Found
npmGlobalPackages:
react-native: Not Found

Steps to reproduce

Use this repo to easily output and diff performance.now() timestamps (or create a sample app with a button that outputs the performance.now() timestamp to the console):

<Button
  onPress={() => console.log(global.performance.now())}
  title="performance.now()"
/>
  1. Start the app, tap the button to record the timestamp
  2. Go to the device settings, move the device date one day forward
  3. Go back to the app, tap the button again

The difference between the two timestamps will be >24h.
That is not the case when doing the same repro steps on RN 0.67.4 (since the clock is monotonic).

Snack, code example, screenshot, or link to a repository

Use this repo to easily output and diff performance.now() timestamps.

React Native 0.67

The diff between the two timestamps after moving the clock 24h forward is <10 seconds (the time it took to change the clock)

React Native 0.68

The diff between the two timestamps after moving the clock 24h forward is >24h

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions