flutter / flutter

Flutter makes it easy and fast to build beautiful apps for mobile and beyond
https://flutter.dev
BSD 3-Clause "New" or "Revised" License
166.67k stars 27.61k forks source link

Flutter web apps not working on older versions of Safari and WebKit (pretty important and urgent for us!) #158082

Open milke opened 3 weeks ago

milke commented 3 weeks ago

Steps to reproduce

I don't know if this fits the bug category, but not of the offered issue categories to choose don't fit better with the problem I'd like to report…

Flutter web crashes on Safari and WKWebKit with WebAssembly.compileStreaming is undefined

The problem is that flutter web apps don't work on older versions of Safari and WebKit, which I still need to support. For example, I need to support Safari 14.1.3 on macOS 11.1.17 and flutter application stops working when sending request to www.gstatic.com and trying to load file canvaskit.wasm from there.

Web console reports the following errors:

[Error] Unhandled Promise Rejection: TypeError: WebAssembly.compileStreaming is not a function. (In 'WebAssembly.compileStreaming(fetch(s))', 'WebAssembly.compileStreaming' is undefined)
    g (flutter_bootstrap.js:4:5026)
    (anonymous function) (flutter_bootstrap.js:4:5585)
    asyncFunctionResume
    (anonymous function) (flutter_bootstrap.js:4:5719)
    I (flutter_bootstrap.js:4:5720)
    (anonymous function) (flutter_bootstrap.js:4:7435)
    asyncFunctionResume
    Global Code (flutter_bootstrap.js:20)
[Error] Unhandled Promise Rejection: null
    (anonymous function) (flutter_bootstrap.js:36)
    asyncFunctionResume
    (anonymous function)
    promiseReactionJobWithoutPromise
    promiseReactionJob

We use flutter on web both for our store, available on the web, but also in the WKWebView in one of our applications. Everything works fine in newer versions of Safari and WebKit, but fails on older versions. It used to work on older versions as well, but it stopped working after some flutter update (we regularly update our code with each new flutter release). I don't have clear track when it happened.

Some of the web app I refer to:

https://store.cocoatech.io https://deckr.surf

The current situation is that flutter apps on web are useless for anyone using older Mac/macOS and there still are many such people (and many in our user base).

I wonder if there's something we can do about it from our side? Any way we can modify or patch flutter default behaviour? I wonder if we could patch the javascript if (wasmstuff exists) {} (assuming that would solve the problem)?

Thanks a lot for looking into this and for providing any explanation, insight and solution, as it's really very important to us, and it's pretty urgent.

Expected results

Please see the description of the problem above.

Actual results

Please see the description of the problem above.

Code sample

N/A

Screenshots or Video

N/A

Logs

N/A

Flutter Doctor output

[✓] Flutter (Channel stable, 3.24.4, on macOS 14.7.1 23H222 darwin-arm64, locale en-US)
    • Flutter version 3.24.4 on channel stable at /Users/milke/Developer/flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 603104015d (10 days ago), 2024-10-24 08:01:25 -0700
    • Engine revision db49896cf2
    • Dart version 3.5.4
    • DevTools version 2.37.3

[✗] Android toolchain - develop for Android devices
    ✗ Unable to locate Android SDK.
      Install Android Studio from: https://developer.android.com/studio/index.html
      On first launch it will assist you in installing the Android SDK components.
      (or visit https://flutter.dev/to/macos-android-setup for detailed instructions).
      If the Android SDK has been installed to a custom location, please use
      `flutter config --android-sdk` to update to that location.

[✓] Xcode - develop for iOS and macOS (Xcode 15.3)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Build 15E204a
    • CocoaPods version 1.15.0

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[!] Android Studio (not installed)
    • Android Studio not found; download from https://developer.android.com/studio/index.html
      (or visit https://flutter.dev/to/macos-android-setup for detailed instructions).

[✓] Connected device (3 available)            
    • macOS (desktop)                 • macos                 • darwin-arm64   • macOS 14.7.1 23H222 darwin-arm64
    • Mac Designed for iPad (desktop) • mac-designed-for-ipad • darwin         • macOS 14.7.1 23H222 darwin-arm64
    • Chrome (web)                    • chrome                • web-javascript • Google Chrome 130.0.6723.71

[✓] Network resources
    • All expected network resources are available.

! Doctor found issues in 2 categories.
andrewmallory8 commented 3 weeks ago

I'm having the same issue. Flutter web crashes on Safari and WKWebKit with 'WebAssembly.compileStreaming' is undefined.

You need to add if (WebAssembly.compileStreaming != null) {} before calling it.

Need a fix ASAP. My website is crashing for mac users.

mraleph commented 3 weeks ago

Note that Flutter does not actually officially support Safari 14. See https://docs.flutter.dev/reference/supported-platforms for reference.

The particular issue can probably be easily fixed - you can rewrite bootstrapping code to use non-streaming WebAssembly.compile instead of WebAssembly.compileStreaming (which only became available in Safari 15).

But I find it hard to predict what else will break. cc @yjbanov

darshankawar commented 3 weeks ago

Labeling for team's tracking.

kevmoo commented 2 weeks ago

It's tricky to support browsers 3+ years old that are 4 versions behind.

I'd take a stab at @mraleph suggestion about changing the bootstrap logic.

codetotech commented 2 weeks ago

I think you could only work on google chrome (that's the only full supported browser... in all the platform mac,win,linux), and also better sometimes in the canary version.

hope it help... :)

milke commented 2 weeks ago

The thing is that we have chosen Flutter for our web apps, running inside a WKWebView (Apple's WebKit) window in macOS application, handling purchase, registration, activation etc… Things that can hardly be done inside a regular browser as the communication with other parts of the application is needed. Or it can, but it's far from being user friendly (using a web browser to activate completely separate application?). And now it appears problematic that we've chosen Flutter? At the time we made that decision, Flutter inside a WebView worked on every macOS version we supported.

  1. We use WebKit framework, and it's tied to the OS, not Safari browser. Updating Safari also updates the private "Safari" framework (just their custom version of WebKit), which Safari uses instead of WebKit. WebKit isn't updated.
  2. Currently, our registration and activation doesn't work on anything older than macOS 12 Monterey and we have a huge number of users running older OS versions.
  3. We can't control what browser or OS version (from those we support) our customers choose.
  4. This is, BY FAR, our number one support issue. And it's killing our business by choosing to use Flutter.
  5. @mraleph, @kevmoo, I have no idea how the bootstrap code works. Could you help?
  6. At the very least, add something like if (WebAssembly.compileStreaming) {} so it doesn't crash.
codetotech commented 2 weeks ago

so.... the first thing that I'll try is try to develop the flutter app on chrome. blink use a lot of webkit like code: as: "The major browser makers – Apple, Google, and Mozilla – each have their own browser rendering engines. Apple's Safari is based on WebKit; Google's Chrome and its open source Chromium foundation is based on Blink (forked from WebKit a decade ago)"

It's clear that you have to manage the code between the two situation:

But changes and update are in field everyday... you couldn't support old stuff in a log period....

Have a good luck :)

mraleph commented 2 weeks ago

@codetotech can you stop posting irrelevant comments on the issue? Thanks.

codetotech commented 2 weeks ago

no problem at all... why you think it's irrelevant...? try only to help. have a good day :)

mraleph commented 2 weeks ago
  • @mraleph, @kevmoo, I have no idea how the bootstrap code works. Could you help?

The code which is erroring is originally lives here, it gets compiled into flutter.js which gets pulled into $flutter_sdk/bin/cache/flutter_web_sdk/flutter_js/flutter.js ends up build/web/flutter_bootstrap.js when you build your project.

I think the simplest way for you is to take build/web/flutter_bootstrap.js after you build your project and edit it to avoid compileStreaming... The simplest patch is something like this (flutter_bootstrap.js is minified so I have formatted it first - the diff below is against formatted version):

--- build/web/flutter_bootstrap.orig.js 2024-11-05 11:37:40
+++ build/web/flutter_bootstrap.js  2024-11-05 11:42:30
@@ -185,6 +185,8 @@
         }
     };
     var g = s => {
+        // Fallback to canvaskit.js own loading mechanism instead.
+        if (typeof WebAssembly.compileStreaming === 'undefined') return void 0;
         let t = WebAssembly.compileStreaming(fetch(s));
         return (i, r) => ((async () => {
             let e = await t,
mraleph commented 2 weeks ago

I live it to @yjbanov to make a call if we want to update bootstrapping code to support a browser version which is officially unsupported.

yjbanov commented 1 week ago

We could make that change as a "best effort" attempt to support Safari 14. However, we no longer test on Safari 14, so if things work there, it will be purely by accident.

In general, the best way to support very old target platforms is by using older versions of the Flutter SDK. As your platform support moves to the next version, you upgrade to the corresponding Flutter SDK that supports it (even if it continues being behind the current Flutter stable releases).

yjbanov commented 1 week ago

For small changes like this, we welcome PRs from the community.

milke commented 1 week ago

@yjbanov, thanks for advices and insights.

@mraleph, thanks for the advice and guidance regarding flutter.js and bootstrap.js. I was busy with some other things and I forgot to thank you :-)