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

[wasm] Blazor - Client Side Blazor iOS 13 #16986

Closed
kjpou1 opened this issue Sep 23, 2019 · 82 comments
Closed

[wasm] Blazor - Client Side Blazor iOS 13 #16986

kjpou1 opened this issue Sep 23, 2019 · 82 comments

Comments

@kjpou1
Copy link
Contributor

kjpou1 commented Sep 23, 2019

Well actually iOS 13 Safari version is very buggy with WASM or at least call stack size. I just tested with my iPad and even the samples doesn't work because of 2. - Unhandled Promise Rejection: RangeError: Maximum call stack size exceeded. . Also 3. but this is worarounded by the hint you received on another github post with "var Module;".

The only workaround i found at the moment with the current Safari / iOS 13 version is by modifying the blazor.webassembly.js file and add give some time at startup on some delegates. It work on my iPad, but i cannot test on iPhone, i only have an iPhone 6 and of course Apple dropped iPhone 6 support for iOS 13.

blazor.webassembly.ios13.fix.zip

As i have no alternative, i will put it as an "Opt-in" in my plugin (mainly for iOS), but i wish Webkit will work better in the future.

Actually tested my "big" Business app with my patch, and it seem to work.

Originally posted by @Daddoon in #16144 (comment)

@kjpou1 kjpou1 changed the title [wasm][blazor] Client Side Blazor ios [wasm][blazor] Client Side Blazor iOS 13 Sep 23, 2019
@kjpou1
Copy link
Contributor Author

kjpou1 commented Sep 23, 2019

There has been a PR submitted to rectify the <script>var Module;</script> on iOS 13 dotnet/aspnetcore#13945

@kjpou1
Copy link
Contributor Author

kjpou1 commented Sep 23, 2019

@Daddoon Hello Daddoon

Can you outline the modifications that were made to your blazor.webassembly.io13.fix.zip also which delegates exactly are you adding startup time?

@kjpou1 kjpou1 changed the title [wasm][blazor] Client Side Blazor iOS 13 [wasm] Blazor - Client Side Blazor iOS 13 Sep 23, 2019
@Daddoon
Copy link

Daddoon commented Sep 23, 2019

As i have modified the minified version, it would be hard to say what is the real function name in your source code.

Considering the unminifying of the minified version, here are the two modified zone (left is original unminified, right the 'fixed' one):

diff1

diff2

Of course as you can see all the 'window.Blazor.isStarted' stuff is just an hack of my in order to not use my workaround after Blazor booter properly, preventing to slow it down unecessary.

In my opinion, the "workload" issue is maybe not exactly in this piece of code but in the underlying called delegate, but i'm not sure, but as it's about a Maximum call size exceeded error...

I have tought that delaying with setTimeout would then add the task on another call stack, and the return value seem not to be expected in any parent when called from here, so it seemed safe.

But as you mentioned in another post, it's maybe not related, and maybe about a workload in WASM Bindings/Web worker, and maybe this is just a "side effect".

At least, this fix worked for my iPhone 6s i just bought for testing (this is the lowest Apple device now accepting iOS 13).

It is not the most ideal scenario to wait 2 seconds / 4 seconds with my workaround (because called twice before boot). But as i use Blazor mainly as mobile app framework with BlazorMobile, the waiting may be tolerated atm.

@kjpou1
Copy link
Contributor Author

kjpou1 commented Sep 23, 2019

Yeah not sure myself where those are in the Blazor source code. Maybe we can get someone from Blazor to chime in on this as well.

Thanks for the info.

@kjpou1
Copy link
Contributor Author

kjpou1 commented Sep 23, 2019

Oh one other thing. What exactly did the mod fix? Was it for the stack exceeded? That might be able to guide us the right direction.

@Daddoon
Copy link

Daddoon commented Sep 23, 2019

I don't know exactly what the mod fixed.

I assumed that it was maybe too much recursion:

  • In parent Promise
  • In child delegate execution

And as all theses events was chained at startup, i assumed that because of iOS 13 regression, it was exhausting the Safari call stack size.

By calling the setTimeout, because the "fixed" place does not expect a return value, i assumed it was safe to "break" the call stack chain by calling setTimeout, as i have read on the internet that delaying a Promise through a setTimeout tend to put the code to be executed on a new fresh call stack.

In this case it is not entirely true, as if i don't wait 2 seconds (on iPhone 6s), it will fail at the first or second call, very fast.

So in my opinion, maybe the global call stack of Safari is exceeded at Blazor boot. Maybe a solution would be to chain events differently, with less Promise style, and more with a procedural style. But i'm not a Javascript expert, and also, this is only related to Safari in current release.

So yes, for your second question, the fix was for the stack exceeded error. I had to add the var Module; trick you mentionned on another issue/pull request, in order to fix a first error on iOS (yes it's not only OSX Catalina), but the stack exceeded error happen just after this Module declaration fix.

@GerritBergen
Copy link

@Daddoon I'm in the same situation as you were. Latest iPhone I have is an iPhone 6, so I'm a kinda blind to this error.

I just want to confirm, you're able to completely load a blazor app in iOS 13.1 using your workaround file?

@Daddoon
Copy link

Daddoon commented Sep 25, 2019

Hi @GerritBergen

Yes, i have no problem using my business app on iOS 13.1 (still the beta version to be precise) with my workaround. Just be conscient that this workaround create a total additional delay of 4 seconds at startup.

  • As the original blazor.webassembly.js is also injected in your project at compile, maybe you will have to use a different name in your index.html page in order to no be overriden. But honestly i didn't tested what would be the first and/or last to be copied/overwritten.
  • Also i didn't have checked since my fix if the blazor.webassembly.js code changed between the previous release and the actual shipped 2/3 days ago. You may have to make a diff between the older original and the actual original file. If something has been updated, i advise you to apply yourself the fix on the new version, as i don't have tested/updated yet to the newest release, and i'm more on a shipping plan at the moment than updating the base code.
  • My fix worked on iPhone 6s (oldest/lowest device for iOS 13, even if not tested on iPhone SE)
  • My fix worked on iPad (newest one).
  • I was able to make my business app completly.

@Daddoon
Copy link

Daddoon commented Sep 26, 2019

@GerritBergen just forgot to precise that you must also add a var Module declaration before blazor init, except if the Microsoft PR has been already done. Talking about this subject in my doc

@GerritBergen
Copy link

@Daddoon ok thanks! I'll try this out tomorrow

@chucker
Copy link

chucker commented Sep 27, 2019

Yeah not sure myself where those are in the Blazor source code.

The exact code looks like an awaiter generated by the TypeScript compiler, but the symbol shouldAutoStart can be found in the original TypeScript.

@Daddoon
Copy link

Daddoon commented Sep 27, 2019

@chucker Haha, thanks to your search, i'm pretty sure that the weird behavior on IE11 with server implementation not starting automatically is because of the document.currentScript property not existing at all on Internet Explorer.

Sorry for the off topic!

@GerritBergen
Copy link

@Daddoon I borrowed a friends iOS 13 device and like you said, nothing worked. BUT, after applying your suggestions I was able to get up and running again. Thank you!

Just for reference I had to apply both, <script>var Module;</script>, as well as your workaround in the latest blazor.webassembly.js to get things working. Without both the app wouldn't work.

Thanks again!

@Daddoon
Copy link

Daddoon commented Sep 27, 2019

Happy to hear that !

@kjpou1
Copy link
Contributor Author

kjpou1 commented Oct 1, 2019

Hello all there has been a PR submitted to AspNetCore that fixes the Stack Exceeded problem. dotnet/aspnetcore#14605

@kjpou1
Copy link
Contributor Author

kjpou1 commented Oct 1, 2019

Associated PR here: dotnet/aspnetcore#14576

@Daddoon
Copy link

Daddoon commented Oct 1, 2019

Thanks for your feedback @kjpou1 !
Seems to be a great PR!

Any clue when the next Blazor WASM preview will be release with theses PR ?

It's only for knowing if i must keep my previous workarounds integrated for my next BlazorMobile release on the iOS side, or if i can drop it very soon.

@chucker
Copy link

chucker commented Oct 11, 2019

@Daddoon probably as part of 3.1.0-preview1, which should come out any day now.

@Daddoon
Copy link

Daddoon commented Oct 11, 2019

@chucker I'm not totally sure by reading this issue, but i'm not sure if it's related or not.

@kjpou1 Sorry to bother you, but do you have any informations about that ?

@chucker
Copy link

chucker commented Oct 11, 2019

@Daddoon oh, I see. I had assumed these would be fixed/worked around by now, but Steve makes a good point that the underlying issue should be fixed on Apple's part.

@Daddoon
Copy link

Daddoon commented Oct 11, 2019

oopsies! Didn't seen #17264 ! If it is included in the next preview it should work! I don't know what is the Mono / Microsoft frame for this.

Yes Apple should work on that, but i'm afraid of their very slow udpdate pace...

Still having my "fix", even if in my opinion it's just a hack that doesn't fix the deeper problem that can occur at any moment.

@kjpou1
Copy link
Contributor Author

kjpou1 commented Oct 11, 2019

The #17264 is looking promising. I am not sure of the time frame and this may miss the preview schedule that Blazor is on.

@Daddoon
Copy link

Daddoon commented Oct 11, 2019

Thanks for the feedback @kjpou1 ! Greatly appreciated!

@chucker
Copy link

chucker commented Feb 16, 2020

Same Here. Why is this issue closed then?

Because the original issue is fixed. Please provide more information (iOS version, Blazor/.NET Core version) and ideally a test case.

@Daddoon
Copy link

Daddoon commented Feb 16, 2020

Same Here. Why is this issue closed then?

Because the original issue is fixed. Please provide more information (iOS version, Blazor/.NET Core version) and ideally a test case.

Done in this issue here #16986 (comment) 😁

@jaykrell
Copy link
Contributor

This should be fixed by the combination of:
#18697
#18734

as well there are changes on the Apple side that also fix it.

@Daddoon
Copy link

Daddoon commented Feb 16, 2020

This should be fixed by the combination of:
#18697
#18734

as well there are changes on the Apple side that also fix it.

Thanks for all this work !!
Good to hear updates about that, also thanks to you i have seen that there is already an issue opened here : #18646

I will subscribe to this issue then.

@mobinseven
Copy link

Because the original issue is fixed. Please provide more information (iOS version, Blazor/.NET Core version) and ideally a test case.

  • iOS 13.3.1 on iPhone 7+

  • Blazor 3.2.0-preview1.20073.1

  • The project I'm working on is BlazorBoilerplate. Yes it is not a minimal app as the problem won't happen on minimal apps (Like FlightFinder sample which works flawlessly on the device mentioned above). The project has no issue on iOS 12.4.

@mobinseven
Copy link

Experts say it is a WebKit problem:

Status resolved, but reported as still causing issues. It's fixed in a developer preview, so will take time to land.

WebKit Bugzilla

@chucker
Copy link

chucker commented Feb 18, 2020

@mobinseven I took a look (tried to run BlazorBoilerplate on iOS 13.4b1 on iPhone 11), and unfortunately, this is another instance of WASM: RangeError: Maximum call stack size exceeded.

While #15981 is closed, this is also being visited in #18646 and #12357. (Though contrary to that one, BlazorBoilerplate does run on Safari on macOS, which I believe has a higher call stack limit.)

@jeromelaban are you continuing to work on this? Will a future 3.2 preview include mitigations?
Thanks in advance!

@joshlang
Copy link

Ditto.

WASM: RangeError: Maximum call stack size exceeded from blazor.webassembly.js:1:34699 on iPhone 11 safari, but works fine on desktop Safari. Using latest preview.

@arivera12
Copy link

Why this is closed it still doesn't work on ios iphone and ipad I am still receiving the error message WASM: RangeError: Maximum call stack size exceeded.

@chucker
Copy link

chucker commented Mar 5, 2020

@arivera12 they‘re working on it in other issues. See my comment above.

@arivera12
Copy link

@chucker I see. Hope this gets fix ASAP. I have an app already running on production and website on iphone is broken...

@chucker
Copy link

chucker commented Mar 5, 2020

While I understand your frustration, note that Blazor WebAssembly isn’t considered production-ready until the release in May.

But! You can patch a workaround in to make the app slower, but work alright in iOS. Check @Daddoon’s comments for a custom JS file.

@Daddoon
Copy link

Daddoon commented Mar 5, 2020

@chucker Note that only the boot is slower. Then it's the regular speed.

@Daddoon
Copy link

Daddoon commented Mar 5, 2020

If you take the "patch" route, you may just do some conditionnal check before booting your app.
If you detect that the browser is iOS / Safari, include my patch instead of the original blazor.webassembly.js file.

This way, your regular clients browser will not be affected with this workaround, only iOS.

@arivera12
Copy link

arivera12 commented Mar 5, 2020

@Daddoon I have been playing around since yesterday with your project BlazorMobile seems awesome solution. Its your patch already included there?

@Daddoon
Copy link

Daddoon commented Mar 5, 2020

Yes it's already included in BlazorMobile projects and actually, the modified file posted here is the one stored in my assemblies for the iOS support.

I made it more convenient (in my opinion) on BlazorMobile, as you just have to choose to opt-in or not in your project.

By default the regular blazor.webassembly.js file is loaded, but on the iOS project, in AppDelegate.cs you will see theses lines:

            if (int.TryParse(UIDevice.CurrentDevice.SystemVersion.Split('.')[0], out int majorVersion) && majorVersion >= 13)
            {
                BlazorWebViewService.EnableDelayedStartPatch();
            }

So if you keep this line present, when iOS platform will be booted, it will replace the blazor.webassembly.js file shipped in your application by a patched one, so you don't have to modify your Blazor HTML project directly to take advantage of the fix.

If Microsoft release a fix in the future you will just have to remove this line to just continue to your regular blazor.webassembly.js file.

But beware, my patch is so always linked to the current supported Blazor version. This mean that if you update your Blazor project to a new version, but that i didn't updated my codebase for this patch, your app will likely don't work. This is the only downside of having to patch the thing externally.

This just mean that if you intent to use Blazor with BlazorMobile, try to keep the version of Blazor at the same levels as specified in the Nuget dependencies of BlazorMobile (or as stated in the project documentation).

@Daddoon
Copy link

Daddoon commented Mar 5, 2020

@arivera12 Side note (but offtopic) : I will release a new version of BlazorMobile tomorrow (or in a very short future) that will add new functionnalities of course, but fix some issue you may occur at build time possibly (like build error and you have to make it build twice).

This will be fixed if it occur.

@arivera12
Copy link

@Daddoon I try and play with it until you release the new version.
image

@Daddoon
Copy link

Daddoon commented Mar 7, 2020

@arivera12 Update is now available (or if not visible, is on validation on nuget.org) if you want to test.
Sorry for the off-topic,

@arivera12
Copy link

@arivera12 Update is now available (or if not visible, is on validation on nuget.org) if you want to test.
Sorry for the off-topic,
@Daddoon
I will test on this days.

@jeromelaban
Copy link
Contributor

@chucker Apologies I missed your callout. The only workaround I found for this issue in Uno was to delay the initialization of Uno by about 5 seconds (see https://github.com/unoplatform/uno/blob/991eaf1cb29ee20893d07abb26069e6a680b0ed5/src/Uno.UI.Wasm/ts/CoreDispatcher.ts#L58).

Not waiting arbitrarily this long will inevitably fall in some sort of a very very short stack, on all safari versions (macOS included). From what I could find out, it seems that Safari is doing some sort of setTimeout(0) reentrancy optimization during the first few seconds of a page run, instead of dispatching those (and reset the stack).

@curia-damiano
Copy link

Hi,
I have a OOTB Blazor-client project and it is not working on iPhone/iPadOS 13.3, using Blazor 3.2.0-preview1.20073.1.
Is there any workaround I can put to make it work?

@chucker
Copy link

chucker commented Mar 10, 2020

@curia-damiano yes — you can manually replace blazor.webassembly.js with the one from @Daddoon.

@Daddoon
Copy link

Daddoon commented Mar 10, 2020

@curia-damiano yes — you can manually replace blazor.webassembly.js with the one from @Daddoon.

Haha you just posted before I click on comment myself.

@curia-damiano , @chucker is talking about this comment : #16986 (comment) . Also the workaround route taken is similar to the Uno project as I see from @jeromelaban comment

@curia-damiano
Copy link

Hi all,
I can confirm the script of @Daddoon works correctly in all environments, including iPhone and iPadOS.
The drawback is that during initialization there is a delay of 4 seconds...
I hope the next version of Blazor will fix it.

@Daddoon
Copy link

Daddoon commented Mar 11, 2020

You may rename the specific blazor.webassembly.js file, and switch it only if WebKit is detected ? This way you will only load this patch when Safari / WebKit is detected, therefore other browsers will not be affected.

@curia-damiano
Copy link

Currently I have post-build (for local debugging) and post-publish scripts that replace the file entirely.
I really hope in a fix by GA time.

@Daddoon
Copy link

Daddoon commented Mar 11, 2020

Issue is maybe fixed ! See #18646 (comment)

For anyone using my patch, please remove it if using the new version !

@curia-damiano
Copy link

Hi @Daddoon and co., I confirm that Preview 2 works fine now even on iPhone and iPad :-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment