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: browser compatibility policy #28360

Open
neelance opened this issue Oct 24, 2018 · 33 comments
Open

wasm: browser compatibility policy #28360

neelance opened this issue Oct 24, 2018 · 33 comments
Labels
Milestone

Comments

@neelance
Copy link
Member

@neelance neelance commented Oct 24, 2018

I would like to propose a discussion on how we want to handle browser compatibility. There are several features being worked on: https://github.com/WebAssembly/proposals When do we want to use them? Do we want to offer backwards-compatibility?

Here are my own thoughts, open for debate:

(1) Go's support for WebAssembly is experimental and it should stay experimental at least until WebAssembly itself is fully standardized (right now the main spec is still in "Phase 2 - Proposed Spec Text Available").

(2) The WebAssembly project itself has no clear answer yet on how feature tests and backwards compatibility should work, see https://webassembly.org/docs/feature-test/

(3) Modern browsers (except Safari) have auto-update mechanisms, so staying with the latest version shouldn't be an issue for most users.

Due to (1), (2) and (3) I would opt for no backwards compatibility as long as Go's support for WebAssembly is experimental.

New WebAssembly features can be adopted as soon as they are marked as "standardized" and are supported by the latest stable Chrome, Firefox, Edge and Safari (on desktop).

@neelance
Copy link
Member Author

@neelance neelance commented Oct 24, 2018

@neelance neelance changed the title wasm: Browser compatibility policy wasm: browser compatibility policy Oct 24, 2018
@bradfitz
Copy link
Contributor

@bradfitz bradfitz commented Oct 24, 2018

This bug is a little abstract, so this answer is somewhat vague, but:

I'm fine with treating experimental things as experimental, but we should start trying to minimize how often we break users for doing basic things using just the base "MVP WebAssembly" bits. It sounds like everybody's cool with the syscall/js.NewCallback change, but that's the sort of change we shouldn't be making every release.

For experimental new features of WebAssembly, I'd prefer them to be opt-in somehow with associated "This is super experimental!" documentation on the opt-in switch, at least where possible. At least document the state of the compatibility policy in, say, the syscall/js package comment and/or release notes.

@neelance
Copy link
Member Author

@neelance neelance commented Oct 24, 2018

Yes, I agree that we should aim for keeping the API stable. This issue however was mainly about browser compatibility.

The features in question wouldn't add new API, but improve performance or reduce output size. Some examples:

  • a builtin memcpy operation
  • other operations that currently require a slow workaround
  • advanced memory operations so we don't have to request 1 GB of memory at startup
  • support for threads

Here are some options we have:

  • Not use the new features, stay with the MVP features. (This would mean suboptimal performance.)
  • Add compiler flags to choose which features to use. (Go usually avoids compiler flags.)
  • Output multiple wasm binaries using different feature sets.
  • Build a special decoder that can polyfill unsupported features at load time. (This will probably be the best solution at some point, but is also complicated and will likely be tackled by the WebAssembly project itself.)
  • No backwards compatibility for now.

Given these options I would prefer to not have backwards compatibility right now and as soon as feature testing is possible I would add some warning mechanism that tells the user to upgrade the browser.

@myitcv
Copy link
Member

@myitcv myitcv commented Oct 24, 2018

I'm guessing we don't want to use different values of GOOS here? GOOS=chrome etc...

@neelance
Copy link
Member Author

@neelance neelance commented Oct 24, 2018

I'm guessing we don't want to use different values of GOOS here? GOOS=chrome etc...

More GOOS or GOARCH values are cumbersome. Having just one for chrome wouldn't be enough, you would need to target browser versions or generations, e.g. wasm-10-2018.

@bradfitz
Copy link
Contributor

@bradfitz bradfitz commented Oct 24, 2018

Let's use memcpy as an example:

Even without an official feature detection API, can we try to use it in runtime init & catch a fault & set a bool about whether to use it? We do that elsewhere in the runtime for other platforms.

Likewise with other stuff.

If we really can't feature detect at all, I'd say we shoudn't use stuff by default until it's in all the major browser's stable releases.

Worst case we could add a GOWASM environment variable like GOARM, GO386, GOMIPS, etc.

@theclapp
Copy link
Contributor

@theclapp theclapp commented Oct 24, 2018

Add compiler flags to choose which features to use. (Go usually avoids compiler flags.)

Do you mean actual compiler flags like -a or -n, or build tags?

Of course, I imagine build tags would suffer from the same issue as GOOS mentioned previously: "Having just one for chrome wouldn't be enough, you would need to target browser versions or generations". But even so, it seems like build tags might allow more flexibility than compiler flags.

@bcmills bcmills added this to the Unreleased milestone Oct 24, 2018
@bcmills bcmills added the DevExp label Oct 24, 2018
@agnivade
Copy link
Contributor

@agnivade agnivade commented Oct 24, 2018

can we try to use it in runtime init & catch a fault & set a bool about whether to use it? We do that elsewhere in the runtime for other platforms.

I think the issue is that the entire wasm code is validated AOT. As explained here (https://webassembly.org/docs/feature-test/) -

Since some WebAssembly features add operators and all WebAssembly code in a module is validated ahead-of-time, the usual JavaScript feature detection pattern:

if (foo)
    foo();
else
    alternativeToFoo();
won’t work in WebAssembly (if foo isn’t supported, foo() will fail to validate).

I would recommend against more flags or environment variables. Given that wasm is a fast moving platform and it is much easier to upgrade browsers than operating systems.

Not use the new features, stay with the MVP features. (This would mean suboptimal performance.)

Perhaps we can delay new features by one release, so that we give enough time for everybody to catch up to the latest browser version ?

@neelance
Copy link
Member Author

@neelance neelance commented Oct 24, 2018

can we try to use it in runtime init & catch a fault & set a bool about whether to use it? We do that elsewhere in the runtime for other platforms.

I think the issue is that the entire wasm code is validated AOT.

Right. The WebAssembly loader will reject the binary if there are any unsupported operations. The runtime init will not be executed. Currently the only way to do feature detection is to try to load a wasm binary and if it fails then load a different binary.

If we really can't feature detect at all, I'd say we shoudn't use stuff by default until it's in all the major browser's stable releases.

In my first post I suggested "New WebAssembly features can be adopted as soon as they are marked as "standardized" and are supported by the latest stable Chrome, Firefox, Edge and Safari (on desktop)." @bradfitz This is exactly what you mean, isn't it?

Perhaps we can delay new features by one release, so that we give enough time for everybody to catch up to the latest browser version ?

Sounds like a good idea. Maybe 2 or 3 months after the feature has been released?

@bradfitz
Copy link
Contributor

@bradfitz bradfitz commented Oct 24, 2018

In my first post I suggested "New WebAssembly features can be adopted as soon as they are marked as "standardized" and are supported by the latest stable Chrome, Firefox, Edge and Safari (on desktop)." @bradfitz This is exactly what you mean, isn't it?

Yeah.

But if you want to do better earlier, I think it'd be fine to use a GOWASM environment variable to opt-in to newer features that aren't as widely available.

The default should be to produce a binary that works everywhere, but if you want to use something more experimental that only works on one browser, GOWASM=threads,foo,bar seems fine to me at least.

@djhworld
Copy link

@djhworld djhworld commented Oct 25, 2018

New WebAssembly features can be adopted as soon as they are marked as "standardized"

I think this should be the gate to decide whether to implement, rather than relying on the release train of the browsers.

I agree with @bradfitz though to maybe put the bleeding edge stuff behind some flags.

On the flipside that's getting back to the bad old days of "best ran on X browser!" badges, but that's not a Go problem 😄

@marwan-at-work
Copy link
Contributor

@marwan-at-work marwan-at-work commented Nov 26, 2018

One reason to include new WASM features, and not wait 2-3 months, is that users of such features can give feedback on how Go interacts with them so that things are tuned/fixed by the time they are standardized.

@justinclift
Copy link

@justinclift justinclift commented Nov 26, 2018

Yep, there are definitely people around in the Go Community who are chomping at the bit to try out the new browser Wasm capabilities, such as threads. Giving us the ability to try these bleeding edge things does help. 😄

@andreas-jonsson
Copy link

@andreas-jonsson andreas-jonsson commented Mar 19, 2019

@neelance Do you know what would be needed/changed in the runtime to make threads a reality? (What are the challenges?)

Perhaps support could be added gradually first focus on atomic instructions and the bulk mem-ops...

Btw. Do we need bulk memory operations for threads in Go since the runtime only needs a pool of threads. (GOMAXPROCS) So re-initializing the data-segment would perhaps be okey?

Can I help in any way?

@neelance
Copy link
Member Author

@neelance neelance commented Mar 19, 2019

I haven't yet started to look into threads and no concrete plans either. I think I'll wait until the proposal gets to phase 3: https://github.com/WebAssembly/proposals

How are bulk memory operations related to threads?

@bradfitz
Copy link
Contributor

@bradfitz bradfitz commented Mar 19, 2019

By request from @neelance, let me restate my proposed policy from my earlier comment (#28360 (comment)) more clearly:

I think the Go default wasm output should be something that runs on the latest stable releases of Chrome, Edge, Safari, Firefox, iOS Safari, and Android Browser.

That is, WebAssembly should work by default "everywhere", where everywhere means those 6 browsers.

Anything that's either:

a) not supported by those 6 browsers,
b) not yet standardized by WebAssembly

.... should be behind a GOWASM=foo flag, since we can't really feature detect on webassembly at runtime.

@neelance
Copy link
Member Author

@neelance neelance commented Mar 19, 2019

Okay, this is the same as I was proposing, except that you list more browsers.

To clarify: For Safari, iOS Safari and Android Browser, how exactly do we define "latest stable release"? New versions of these browsers are sometimes bound to OS upgrades.

@neelance
Copy link
Member Author

@neelance neelance commented Mar 19, 2019

Based on https://go-review.googlesource.com/c/build/+/168060/1#message-869955fa1d2b803f63e4aa2b3ed0de87af2b5d9b I think we need to add:

c) not yet supported by the Node.js LTS release that gets shipped by Debian.

@bradfitz
Copy link
Contributor

@bradfitz bradfitz commented Mar 19, 2019

To clarify: For Safari, iOS Safari and Android Browser, how exactly do we define "latest stable release"? New versions of these browsers are sometimes bound to OS upgrades.

Good point about Safari. For iOS, latest iOS is fine. That doesn't work quite as well for desktop, but I'm fine also saying latest macOS only there.

For Android Browser: that's evergreen these days, no?

c) not yet supported by the Node.js LTS release that gets shipped by Debian.

I'd soften that to say whatever Debian-provided stable-backports package exists. Currently that's:

https://packages.debian.org/stretch-backports/nodejs (8.11.1)

@neelance
Copy link
Member Author

@neelance neelance commented Mar 19, 2019

For Android Browser: that's evergreen these days, no?

Could be, I'm not sure.

I'd soften that to say whatever Debian-provided stable-backports package exists.

This does not seem like a good choice to me. Reasons:

  • The backport does not seem properly maintained. Version 8.11.1 got released on 2018-03-29, but the latest 8.x release is 8.15.1 released on 2019-02-28. So the backported version is missing 3 security releases and countless bugfixes.
  • The current "active LTS" version of Node.js is 10.x, version 8.x is in "maintenance LTS" mode.
  • The latest Node.js 8.x, which is 8.15.1, ships with V8 6.2.414, which is the same as Chome 62 used, released on 2017-10-17. This seems pretty old.

So if this would be our requirement, then the browser requirements probably wouldn't matter any more.

@bradfitz
Copy link
Contributor

@bradfitz bradfitz commented Mar 19, 2019

Would using latest active LTS be sufficient for you? Otherwise let's just ignore nodejs for our wasm policy reasons. Nodejs people with a few servers can update. Millions of end users with browsers is harder.

@neelance
Copy link
Member Author

@neelance neelance commented Mar 20, 2019

Let's maybe postpone the decision until the other requirements are met and then we can see how much Node.js is behind.

@andreas-jonsson
Copy link

@andreas-jonsson andreas-jonsson commented Mar 20, 2019

I haven't yet started to look into threads and no concrete plans either. I think I'll wait until the proposal gets to phase 3: https://github.com/WebAssembly/proposals

How are bulk memory operations related to threads?

Okey. Sorry. I thought the tread proposal for for wasm was at a much later state of development since it seemed to be supported in at least some browsers.

I think conditional segment initialization is part of that proposal. I guess something like that would be necessary to avoid initializing memory twice?

As a reference, this was a nice read about the subject.

@neelance
Copy link
Member Author

@neelance neelance commented Mar 21, 2019

As a reference, this was a nice read about the subject.

Thanks, this is a good overview.

@bradfitz
Copy link
Contributor

@bradfitz bradfitz commented May 2, 2019

We just updated our builders from nodejs v8.11.1 to nodejs v12.1.0 for #31282

But I continue to believe that Linux distros' current version of nodejs doesn't matter at all. Our WebAssembly version policy should be based solely on browsers.

@neelance
Copy link
Member Author

@neelance neelance commented Aug 15, 2019

I did some testing of the current feature support:

  signext satconv
Node.js 10 (LTS) with flag with flag
Node.js 12.8.0 (current) yes yes
Chrome 76 yes yes
Chrome Mobile 75 yes yes
Firefox 68.0.2 yes yes
Edge 18 yes yes
Safari 12.1.1 no no
Safari Tech Preview 13.1 no no

It seems like Apple is not interested in supporting new WebAssembly features, even the Safari Tech Preview has no support.

@hajimehoshi
Copy link
Member

@hajimehoshi hajimehoshi commented Sep 2, 2020

(1) Go's support for WebAssembly is experimental and it should stay experimental at least until WebAssembly itself is fully standardized (right now the main spec is still in "Phase 2 - Proposed Spec Text Available").

Now WebAssembly is versioned 1.0, is this issue still valid?

@neelance
Copy link
Member Author

@neelance neelance commented Sep 29, 2020

There is now a table that shows which browsers/engines support which WebAssembly features: https://webassembly.org/roadmap/

Unfortunately Safari is still showing no effort at all to keep up with the evolution of WebAssembly. I am not sure what to do... Would it be reasonable to drop support for Safari?

@advanderveer
Copy link

@advanderveer advanderveer commented Oct 11, 2020

There is now a table that shows which browsers/engines support which WebAssembly features: https://webassembly.org/roadmap/

Unfortunately Safari is still showing no effort at all to keep up with the evolution of WebAssembly. I am not sure what to do... Would it be reasonable to drop support for Safari?

I hope that decisions is not made lightly, Safari has almost a 17% market share according to these metrics. Maybe it is worth asking the WASM group how they are dealing with this and are in the know on how Safari's roadmap looks like (at least roughly)? Also, maybe it is worth investigating how other languages (Rust, C#) are dealing with Safari as a target for WASM improvements

I'm not a an expert and don't know what the 'signext' and 'satconv' features bring to the table. But maybe it can be left up to the developer to decide if they want to drop Safari support for those features?

@neelance
Copy link
Member Author

@neelance neelance commented Oct 12, 2020

I hope that decisions is not made lightly

Just collecting data and feedback at the moment.

Safari has almost a 17% market share according to these metrics

Yes, this is why I am quite hesitant. However, I asked for feedback on the Gophers Slack and got 13 upvotes and zero downvotes for removing Safari, see https://gophers.slack.com/archives/C4GU6CHSQ/p1601418152003700.

Maybe it is worth asking the WASM group

Good idea. Feel free to do so if you find a proper place for asking. It fits the situation that on https://webassembly.org/community/feedback/ there are links for V8, Firefox and Edge, but not for Safari.

maybe it is worth investigating how other languages (Rust, C#) are dealing with Safari

I've looked into Rust and it seems that at the moment it still supports Safari.

I'm not a an expert and don't know what the 'signext' and 'satconv' features bring to the table.

This is not about signext and satconv. These can be toggled with a flag quite easily. With reference types or theads it would be much harder to support two modes at the same time.

@advanderveer
Copy link

@advanderveer advanderveer commented Oct 13, 2020

Thank you for the quick response and hopefully it didn't feel like I was coming in too hot! I am just really hoping for Go to become a stable medium for targeting the web on all platforms and all browsers. Heck, i've even put a lot of effort into getting Go wasm to run on IE11. I basically stumbled upon this thread by accident and felt a bit disheartened that the decision to drop Safari was even on the table.

Of course I'm just a single voice on the internet and other's usecase may vary so - indeed - it is a good idea to gather more feedback. But I do believe that it needs a wider audience than just the Gopher slack. With your permission I will post a link to this discussion on the Golang subreddit and the golang-dev google groups.

The other side of the discussion is having overview of what is gained when Safari support is dropped. You mention Threads, maybe there are other important features. As my memory serves there is also an open issue to reduce the WASM filesize that requires browser advancements.

Good idea. Feel free to do so if you find a proper place for asking.

I was actually hoping that you in your official capacity as a maintainer for Go's WASM would have communications with the web assembly group in some sort of way. It's unlikely that I would get any insights in the Safari roadmap.

@neelance
Copy link
Member Author

@neelance neelance commented Oct 15, 2020

Thank you for the quick response and hopefully it didn't feel like I was coming in too hot!

All good. 👍

i've even put a lot of effort into getting Go wasm to run on IE11.

Wow, nice! Couldn't we use this as a fallback for Safari, too?

With your permission I will post a link to this discussion on the Golang subreddit and the golang-dev google groups.

Sure, go ahead. Maybe golang-nuts instead of golang-dev, though.

The other side of the discussion is having overview of what is gained when Safari support is dropped.

I'll write a message to this thread as soon as it actively prevents me from starting to work on some feature.

As my memory serves there is also an open issue to reduce the WASM filesize that requires browser advancements.

That would probably be https://github.com/WebAssembly/funclets. Unfortunately the proposal is stalled because of politics (it would be very hard for V8 to support it).

I was actually hoping that you in your official capacity as a maintainer for Go's WASM would have communications with the web assembly group in some sort of way.

Nope, I have not.

@Splizard
Copy link

@Splizard Splizard commented Oct 25, 2020

Would it be reasonable to drop support for Safari?

Keep in mind that Safari is the only way to target IOS.

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

Successfully merging a pull request may close this issue.

None yet
You can’t perform that action at this time.