Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Regression 0.62.2] requestIdleCallback is never called on iOS #28602

Closed
Freddy03h opened this issue Apr 12, 2020 · 11 comments
Closed

[Regression 0.62.2] requestIdleCallback is never called on iOS #28602

Freddy03h opened this issue Apr 12, 2020 · 11 comments
Labels
Impact: Regression Describes a behavior that used to work on a prior release, but stopped working recently. Platform: iOS iOS applications. Resolution: Fixed A PR that fixes this issue has been merged.

Comments

@Freddy03h
Copy link
Contributor

Description

requestIdleCallback is never called on iOS. On a debug or release mode the behavior is the same. On Android it still work as expected.
The only way for requestIdleCallback to be called on iOS is by providing an timeout option (but all called of requestIdleCallback will be with didTimeout…).

It's a regression in 0.62.X, it worked well on 0.61.5 (and since, at least, 0.47.X on my own app).

React Native version:

System:
    OS: macOS 10.15.4
    CPU: (4) x64 Intel(R) Core(TM) i5-6267U CPU @ 2.90GHz
    Memory: 21.85 MB / 16.00 GB
    Shell: 5.7.1 - /bin/zsh
  Binaries:
    Node: 12.14.1 - /var/folders/68/7qlptmf573d5fzhxlhc6tfvm0000gn/T/yarn--1586712574681-0.7718023604103352/node
    Yarn: 1.19.1 - /var/folders/68/7qlptmf573d5fzhxlhc6tfvm0000gn/T/yarn--1586712574681-0.7718023604103352/yarn
    npm: 6.13.4 - ~/.nvm/versions/node/v12.14.1/bin/npm
    Watchman: 4.9.0 - /usr/local/bin/watchman
  Managers:
    CocoaPods: 1.8.4 - /Users/freddy/.rbenv/shims/pod
  SDKs:
    iOS SDK:
      Platforms: iOS 13.4, DriverKit 19.0, macOS 10.15, tvOS 13.4, watchOS 6.2
    Android SDK:
      API Levels: 23, 24, 25, 26, 27, 28, 29
      Build Tools: 23.0.1, 23.0.3, 24.0.3, 25.0.0, 25.0.2, 25.0.3, 26.0.1, 26.0.2, 26.0.3, 27.0.3, 28.0.1, 28.0.2, 28.0.3, 29.0.2, 29.0.3
      System Images: android-23 | Intel x86 Atom, android-23 | Intel x86 Atom_64, android-23 | Google APIs ARM EABI v7a, android-23 | Google APIs Intel x86 Atom, android-23 | Google APIs Intel x86 Atom_64, android-25 | Google APIs ARM EABI v7a, android-25 | Google APIs Intel x86 Atom, android-25 | Google APIs Intel x86 Atom_64, android-25 | Google Play Intel x86 Atom, android-26 | Google APIs Intel x86 Atom, android-26 | Google Play Intel x86 Atom, android-27 | Google APIs Intel x86 Atom, android-28 | Google APIs Intel x86 Atom
      Android NDK: Not Found
  IDEs:
    Android Studio: 3.1 AI-173.4819257
    Xcode: 11.4/11E146 - /usr/bin/xcodebuild
  Languages:
    Java: 1.8.0_111 - /usr/bin/javac
    Python: 2.7.16 - /usr/bin/python
  npmPackages:
    @react-native-community/cli: Not Found
    react: 16.11.0 => 16.11.0
    react-native: 0.62.2 => 0.62.2
  npmGlobalPackages:
    *react-native*: Not Found

Steps To Reproduce

  1. Create a fresh new react-native app and install the js dependencies and pods. (I used https://github.com/react-native-community/rn-diff-purge/tree/release/0.62.2/RnDiffApp)
  2. On App.js, inside or outside a function component:
requestIdleCallback(()=> {
  console.log("Never called on iOS, only on Android");
});

Expected Results

Expect to requestIdleCallback work as expected.

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

Expo/Snack is not yet on 0.62, the best way is to create a new project with react native cli or by cloning https://github.com/react-native-community/rn-diff-purge/tree/release/0.62.2/RnDiffApp

Thank you

@react-native-bot react-native-bot added Impact: Regression Describes a behavior that used to work on a prior release, but stopped working recently. Platform: iOS iOS applications. labels Apr 12, 2020
armstrongnate added a commit to instructure/canvas-ios that referenced this issue Apr 23, 2020
RN 0.62.2 [broke requestIdleCallback](facebook/react-native#28602).

refs: MBL-14307
affects: student, teacher
release note: none

Test plan:
* Viewing discussion details should automatically mark replies as read
armstrongnate added a commit to instructure/canvas-ios that referenced this issue Apr 23, 2020
RN 0.62.2 [broke requestIdleCallback](facebook/react-native#28602).

refs: MBL-14307
affects: student, teacher
release note: none

Test plan:
* Viewing discussion details should automatically mark replies as read
@svenlombaert
Copy link

I can confirm that I'm running into this issue as well, thinking it was a swr issue.

@svenlombaert
Copy link

If anyone runs into the issue, you can just polyfill it with something like this for now:

window.requestIdleCallback =
    function(cb) {
        var start = Date.now();
        return setTimeout(function() {
            cb({
                didTimeout: false,
                timeRemaining: function() {
                    return Math.max(0, 50 - (Date.now() - start));
                },
            });
        }, 1);
    };

Taken from https://github.com/pladaria/requestidlecallback-polyfill, but the package itself won't work since window.requestIdleCallback is defined by react-native. So you just have to remove that if.

matt-oakes added a commit to matt-oakes/react-native that referenced this issue Sep 8, 2020
When creating a RCTFrameUpdate, ensure it is created with the correct unix timestamp. This is needed to match the NSTimeInterval type. Previously, it was using the CADisplayLink's "timestamp" property, which is not an NSTimeInterval but is instead a CFTimeInterval. This is the Mach host time converted to seconds, which is the number of seconds since the device was turned on.

This was causing issues with the window.requestIdleCallback timers as the timer code was expecting this "timestamp" property to be a unix timestamp in seconds which was causing the calculations to be done incorrectly and for the callbacks to never be called.

Fixes facebook#28602
@matt-oakes
Copy link
Contributor

@Freddy03h @svenlombaert I have found the issue that's causing this and submitted a PR to fix it. It's easy to fix this yourself using patch-package.

matt-oakes added a commit to matt-oakes/react-native that referenced this issue Sep 10, 2020
This was causing issues with the window.requestIdleCallback timers as the timer code was expecting this "timestamp" property to be a unix timestamp in seconds which was causing the calculations to be done incorrectly and for the callbacks to never be called.

Fixes facebook#28602
@Nantris
Copy link

Nantris commented May 1, 2021

I hope this can get fixed? It's pretty confusing that the function is defined and everything seems right, but then the code just stops executing when we try to use the function. Took me a bit to realize what the issue was since it works fine on Android.

@Freddy03h
Copy link
Contributor Author

I don't know about to following of the issue, I stoped using requestIdleCallback

matt-oakes added a commit to matt-oakes/react-native that referenced this issue Jan 3, 2022
This was causing issues with the window.requestIdleCallback timers as the timer code was expecting this "timestamp" property to be a unix timestamp in seconds which was causing the calculations to be done incorrectly and for the callbacks to never be called.

Fixes facebook#28602
@Nantris
Copy link

Nantris commented Jan 21, 2022

Bump. Any movement on this?

requestIdleCallback isn't supported on iOS, but in that case I would expect React Native would have a dummy function to run, rather than halting execution permanently at the call to window.requestIdleCallback()

@github-actions
Copy link

This issue is stale because it has been open 180 days with no activity. Remove stale label or comment or this will be closed in 7 days.

@github-actions github-actions bot added the Stale There has been a lack of activity on this issue and it may be closed soon. label Apr 20, 2023
@github-actions
Copy link

This issue was closed because it has been stalled for 7 days with no activity.

facebook-github-bot pushed a commit that referenced this issue Jul 12, 2023
Summary:
Fixes #28602

When creating a `RCTFrameUpdate`, ensure it is created with the correct unix timestamp in seconds. This is needed to match the `NSTimeInterval` type defined in the header.

Previously, it was using the `CADisplayLink`'s `timestamp` property, which is not an `NSTimeInterval` but is instead a `CFTimeInterval` (note the different class prefix). This is the host time converted to seconds, which is the number of seconds since the device was turned on and therefore not a unix timestamp as expected.

This was causing issues with the `window.requestIdleCallback` timers as the timer code was expecting this `timestamp` property to be a unix timestamp in seconds which was causing the calculations to be done incorrectly and for the callbacks to never be called. The code does this calculation is here:

https://github.com/facebook/react-native/blob/4d920fe7c991eaec61d229a71df30b0f6c446d38/React/CoreModules/RCTTiming.mm#L262

As one of these is a valid unix timestamp and the other is a much smaller number (number of seconds since device turn on), the `if` statement following this calculation never passes and the callbacks are never called.

This regression seems to have been introduced with this pull request: #26114

## Changelog

<!-- Help reviewers and the release process by writing your own changelog entry. For an example, see:
https://github.com/facebook/react-native/wiki/Changelog
-->

[iOS] [Fixed] - Fixed window.requestIdleCallback not firing on iOS

Pull Request resolved: #29895

Test Plan: I have tested this by patching my React Native code and testing that idle callbacks are correctly called. There is a reproduction case of the issue in the linked issue.

Reviewed By: NickGerleman

Differential Revision: D47381404

Pulled By: sammy-SC

fbshipit-source-id: fd166741889b0084e1def8dedf6e4018adfd570f
@sannajammeh
Copy link

Just wondering is there any update on this in Hermes? Can we run requestIdleCallback on iOS yet?

@gaearon
Copy link
Collaborator

gaearon commented Oct 27, 2023

It appears that the fix was merged in #29895 but I'm not sure which release will contain it. cc @sammy-SC

@cortinico
Copy link
Contributor

It appears that the fix was merged in #29895 but I'm not sure which release will contain it. cc @sammy-SC

@gaearon This (72abed2) will be shipped in 0.73 (it's already included in rc0-rc3)

@cortinico cortinico removed Stale There has been a lack of activity on this issue and it may be closed soon. Needs: Triage 🔍 labels Oct 27, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Impact: Regression Describes a behavior that used to work on a prior release, but stopped working recently. Platform: iOS iOS applications. Resolution: Fixed A PR that fixes this issue has been merged.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants