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

Changing scrollRestoration freezes iOS Safari after swiping to go back (affects all React-based pages) #128

Closed
hippotastic opened this issue Feb 3, 2018 · 9 comments

Comments

@hippotastic
Copy link
Contributor

I noticed a strange bug that affects all React-based pages on iOS Safari (tested on iPhone, iPad with current iOS 11.2.5). You can test it yourself even on big sites, e.g.:

When navigating through the subpages of such React-based pages with iOS Safari and then using the swipe gesture to go back (causing a history popstate transition), Safari freezes up for 2-6 seconds. During this time, the screen is not updated and the user is unable to even scroll the page.

As I wanted to use Gatsby for one of my projects and found this issue there as well, I didn't want to accept this behavior and started debugging. After some hours, I found your following code to be the culprit:

// This helps avoid some jankiness in fighting against the browser's
// default scroll behavior on `POP` transitions.
/* istanbul ignore else: Travis browsers all support this */
if ('scrollRestoration' in window.history) {
	this._oldScrollRestoration = window.history.scrollRestoration;
	window.history.scrollRestoration = 'manual';
} else {
	this._oldScrollRestoration = null;
}

If you comment out the line that sets window.history.scrollRestoration to 'manual', the iOS Safari freeze bug is gone. I'm sure you will be able to find a better solution than just commenting out the line, though.

I realize that the root cause seems to be an iOS Safari bug, but as big projects like React depend on your code, I think it's important for you to find a temporary workaround for this bug. This will improve the user experience of countless React site users until that bug gets fixed by Apple and enough users have updated to a version of Safari that doesn't have this problem.

@taion
Copy link
Owner

taion commented Feb 3, 2018

Oh wow. That's a good catch – weird, too. Just confirmed that this happens on an iPhone X with the latest iOS release. And I see it on mobile.twitter.com too, so it's not just React sites.

@KyleAMathews do you have a reference to any documentation on the Safari bug and if there are any workarounds?

I see someone tweeted this StackOverflow thing: https://stackoverflow.com/questions/47792759/scrollrestoration-set-to-manual-and-swipe-back-functionality-on-safari-ios?stw=2

I guess the right fix is to just sniff for iOS Safari and disable this behavior?

@taion
Copy link
Owner

taion commented Feb 3, 2018

Do you know how to sniff for iOS? I see this on StackOverflow:

var iOS = !!navigator.platform && /iPad|iPhone|iPod/.test(navigator.platform);

This seems like a sensible check to add, but my familiarity with this sort of sniffing is limited. Is this likely to work? cc @jquense

@hippotastic
Copy link
Contributor Author

While I'm not a big fan of browser sniffing in general, your iOS detection code looks ok to me. However, please note that only iOS Safari needs to be excluded. I tested Chrome on iOS as well and it didn't exhibit the scrollRestoration freeze bug.

@taion
Copy link
Owner

taion commented Feb 3, 2018

The heck? So it's not even an iOS WebKit thing – it's just iOS Safari?

@hippotastic
Copy link
Contributor Author

Yes, AFAIK it's just iOS Safari. And there only the swipe gestures. If you navigate back and forth using the arrow buttons in the bottom toolbar, there is no freeze bug.

BTW, you were right about mobile.twitter.com - they use this code in their main bundle:

function() {
  var e = this.props.window;
  e.history && "scrollRestoration"in e.history &&
    (this._prevScrollRestoration = e.history.scrollRestoration,
                    e.history.scrollRestoration = "manual")
}

So, same cause, same effect there as well. How can we make sure Apple is aware of this bug?

@taion
Copy link
Owner

taion commented Feb 4, 2018

I don't know. They probably know already.

Do you want to put together a PR? Just add a check for the browser in the same if.

@hippotastic
Copy link
Contributor Author

I gave it a shot, just let me know what you think. The Travis CI check failed on Firefox, but I don't think this has to do with my changes.

@taion taion closed this as completed in #129 Feb 5, 2018
@chungwong
Copy link

Can we say scroll-behavior currently is disabled(not working) on all IOS devices at this moment?
It does look like somethings have been fixed: https://trac.webkit.org/changeset/226750/webkit

@taion
Copy link
Owner

taion commented Aug 1, 2018

That's not true. scroll-behavior works just fine on iOS. The behavior was a little suboptimal before #129, but now it "just works".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants