Go: wasm: browser compatibility policy

Created on 24 Oct 2018  ·  37Comments  ·  Source: golang/go

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).

Arch-Wasm DevExp

Most helpful comment

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.

All 37 comments

/cc @bradfitz @myitcv @dennwc @theclapp

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.

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.

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

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.

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.

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.

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 ?

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?

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.

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 😄

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.

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. :smile:

@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?

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?

By request from @neelance, let me restate my proposed policy from my earlier comment (https://github.com/golang/go/issues/28360#issuecomment-432853069) 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.

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.

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.

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)

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.

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.

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

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.

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

Thanks, this is a good overview.

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.

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.

(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?

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?

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?

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.

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.

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.

Would it be reasonable to drop support for Safari?

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

@neelance Btw, I've posted the link to this thread on Reddit and Golang nuts yesterday.

I am inclined to suggest that when a dev is preparing a marketing tool such as a website, they should target as wide of an audience as possible. Dropping Safari or IE11 is not prudent at this time as they are significant in the market though not primary.

Output multiple wasm binaries using different feature sets. Splash page detects browser capabilities and deploys appropriate solutions. Let the user decide if they want to use IOS, IE11, or upgrade. Give devs a standard app IPL to handle the alternatives. Do not ask the programmers if they want to drop Safari, they are not stakeholders, and do not ask the marketing guys who do make the decisions or you will end up using JavaScript.

In principle, be inclusive and serve the entire browser community, then optimize using new features using whatever implementation may be the most appropriate use of advanced technology.

@comaldave I have seen this position several times now. It seems like it is not clear that the options are not "less support" vs. "more support". Since it is mostly me working on WebAssembly and carrying legacy support is a lot of work, the options are more along "less support" vs. "no progress on WebAssembly for Go at all". I am working on this for free in my spare time and if I don't feel like putting in the effort for legacy support, then I won't do it. I am not trying to force some conclusion, I just want to point out my position and why I initially started this discussion. There is always a tradeoff.

I totally understand and agree with you. I was expressing an ideal
situation. You are expressing the limits of your bandwidth. The solution is
to have more talented volunteers. I would rather be beaten with a stick
than help you with compliance with Safari archaic refusal to advance. I do
very much want to assist you but my bandwidth is also limited. In point of
fact, I would prefer that you remain on the bleeding age and make it the
best possible product on the most performant platform. I am also hoping
that you might be willing to mentor a talented CS student who is willing
to work on the legacy stuff as well. If it is great on Chome and nowhere
else, then it is a proof of concept, if it works for 80% of users then it
may be marketable, not ideal but usable. And sometimes, you cannot achieve
perfection, you just try to meet minimum specs and ship it on deadline.

What I am trying to do is to train CS students on how to best use what you
are creating, so make no mistake, I very much admire and appreciate your
efforts.

On Tue, Oct 27, 2020 at 7:04 AM Richard Musiol notifications@github.com
wrote:

@comaldave https://github.com/comaldave I have seen this position
several times now. It seems like it is not clear that the options are not
"less support" vs. "more support". Since it is mostly me working on
WebAssembly and carrying legacy support is a lot of work, the options are
more along "less support" vs. "no progress on WebAssembly for Go at all". I
am working on this for free in my spare time and if I don't feel like
putting in the effort for legacy support, then I won't do it. I am not
trying to force some conclusion, I just want to point out my position and
why I initially started this discussion.


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/golang/go/issues/28360#issuecomment-717197250, or
unsubscribe
https://github.com/notifications/unsubscribe-auth/AAAYCWHIGTOIHS72VSGCJODSM2ZOBANCNFSM4F675HFA
.

--

Respectfully submitted,
[image: photo]
David Lynn Skinner
Secretary, Davsk Ltd Co

1-501-436-9086 | 1-870-617-2770 | skinner.[email protected]

https://conf.davsk.net/david
650 S 5th St Apt 88 Arkadelphia AR 71923 | 1-501-201-0414
http://stackoverflow.com/users/3886366/david-skinner
http://github.com/ComalDave/ http://facebook.com/david.lynn.skinner/
http://www.instagram.com/david.lynn.skinner/
http://www.linkedin.com/in/david-l-skinner/
http://twitter.com/SkinnerDavidL http://youtube.com/c/DavidSkinnerDavsk
http://www.pinterest.com/skinnerdavid/

IMPORTANT: The contents of this email and any attachments are confidential.
They are intended for the named recipient(s) only. If you have received
this email by mistake, please notify the sender immediately and do not
disclose the contents to anyone or make copies thereof.
All views and opinions expressed in this email message are the personal
opinions of the author and do not represent those of the company. No
liability can be held for any damages, however, caused, to any recipients
of this message.
No employee or agent is authorized to conclude any binding agreement on
behalf of the company with another party by email without specific
confirmation.
If you received this email in error, please notify us immediately by
sending an e-mail or by calling.
Be like me, be Carbon free - don't print this and save a tree

"Try not to become a man of success, but rather try to become a man of
value." - Albert Einstein.
Create your own email signature
https://www.wisestamp.com/signature-in-email/?utm_source=promotion&utm_medium=signature&utm_campaign=create_your_own&srcid=4651978702585856

Was this page helpful?
0 / 5 - 0 ratings