Hacker News new | past | comments | ask | show | jobs | submit login
Hello wasm-pack (hacks.mozilla.org)
413 points by steveklabnik 10 months ago | hide | past | web | favorite | 155 comments



Does anyone have a good sense of the current performance impact of crossing the boundary between JS and WASM? I've often thought it'd be great to be able to expose high-performance data structures (and other infrastructure-level stuff) via WASM and then make use of them from JavaScript, but I seem to recall that the interop performance cost is currently too high to make it worth doing, which leaves WASM mainly only useful for long-running tasks, such as game engines, expensive graph layout algorithms and so forth.

Edit: https://hacks.mozilla.org/2018/04/javascript-to-rust-and-bac...

> "The wasm-bindgen code generation has been designed with the future host bindings proposal in mind from day 1. As soon as that’s a feature available in WebAssembly, we’ll be able to directly invoke imported functions without any of wasm-bindgen‘s JS shims. Furthermore, this will allow JS engines to aggressively optimize WebAssembly manipulating the DOM as invocations are well-typed and no longer need the argument validation checks that calls from JS need. At that point wasm-bindgen will not only make it easy to work with richer types like strings, but it will also provide best-in-class DOM manipulation performance."


The cost is more than a JS->JS call, but not drastically so. Every argument must be converted from a number to an int32/float32/float64, which for SMI values is a single branch, for heap numbers a branch and a load. For other JS values, a ValueOf() operation on the JS value.

V8 generates little wrappers for these, with inline conversions. It does not currently inline the little wrapper functions, nor use ICs for the conversions inside, since branches are generally enough to get the interesting fast cases.

The idea of a super-expensive call is therefore a bit of a myth. You can try to measure the cost yourself, but be careful! Most microbenchmarks will end up comparing the difference between an inlined JS call (as low as zero overhead) versus a non-inlined WASM->JS or JS->WASM call. The proper comparison would be instead with a non-inlined JS->JS call. Defeating inlining for JS->JS calls is tricky. You can do it with cross-realm calls, or by trying manipulating polymorphism. In either case, it's pretty tricky, so good luck.


If it's nearly impossible to defeat inlining, wouldn't the appropriate comparison be against inlined JS?


You can defeat inlining by using closures:

    function thunk(x){ return function() { x() } }
    const thunkFoo = thunk(foo)
    const thunkBar = thunk(bar)

    for(var i = 0; i < 10000; i++) {
      thunkFoo()
      thunkBar()
    }
This is why the "Maybe you don't need Rust to speed up your JS" author was creating functions dynamically using `new Function()`.

Maybe you cal get away with

    function call(x){ x() }
    for(var i = 0; i < 10000; i++) {
      call(foo)
      call(bar)
    }

I didn't test the latter though, whereas the former is empirically slower if you call more than one thunk in your benckmark loop (a single thunk will have the call inlined).

https://mrale.ph/blog/2018/02/03/maybe-you-dont-need-rust-to...


For v8, doesn’t a try/catch block defeat inlining? It used to, but that was a long time ago.


No, not with TurboFan (since Q2 2017).


It depends how much you are expecting, for instance this WebGL demo does about 15k draw calls per frame on my 2014 MBP with integrated Intel GPU before it drops below 60Hz, that's about 1.8 million WebGL calls per second. On this machine, performance of a native executable is quite similar, so the WASM-to-JS overhead isn't big enough to be noticeable for those 1.8m calls/sec. I know, it's not a really useful benchmark, I guess what I want to say is that for most real-world problems the calling overhead shouldn't matter much, since other things will break down first.

PS: link to demo: http://floooh.github.io/oryol/asmjs/DrawCallPerf.html


I did a basic benchmark [0] when partially porting gl-matrix to a near 1:1 wasm equivalent.

There is some overhead but it seems acceptable. I get drops when calling a wasm function with a lot parameters (see .set).

[0] https://maierfelix.github.io/glmw/mat4/

Note: This benchmark is far from perfect but hopefully can provide some insights


I've read that cryptography algorithms written in wasm (wat format) are nearly as fast as their C implementations.


is there a format called "wat"?? lol


“Web assembly text” format, yes.


World of Warcraft's config files are all ".wtf" so there's that, too.


I cant help but think of the post about stealing password credentials from the site you build by surreptitiously inserting extra code into the published NPM package. Except wasm packages seem like they'd be even harder to detect.

https://hackernoon.com/im-harvesting-credit-card-numbers-and...


I have a package on NPM which is only partially implemented, using it in a production app is a bad idea, a quick glance at the source code or the todo section of the readme makes it pretty obvious. I still gets bug reports and npm says it has hundreds of download every month.

For anything serious, read the source code, at the very least check your dependencies.


fwiw as a former npm registry engineer i can tell u that "hundreds of download every month" likely is a result of the background bot activity npm gets. but your advice is sound! definitely vet your deps before you use them! and YES! read the source.


Is this realistic though? Every time you update a dependency you would have to read its source (and its source dependencies, and their source dependencies...)

To do that well, it would be someone's fulltime job to read and do security audits on all those dependencies.


Last time I went to one of the Bay Area node meetups, that given meetup was being sponsored by just such a company. Can't remember the name, unfortunately.

The idea was though that you'd feed them your package.json and they'd let you know of any vulnerabilities, iirc. Or maybe they had a private repo of packages they'd checked? Can't remember.


Possibly https://snyk.io/ ?


Theoretically, once something is updated all you would have to do is check the diff. Still tedious though.


I look forward to all the clever exploits that result from benign-looking code being added to benign-looking code.


The argument in that article is that it doesn't matter what is in the source. The published package has no guarantees to be from the source.


You could already do this tons of ways. Native modules come to mind.


Which don't run in browsers


Since wasm (currently) requires js to interact with the DOM, you could still read the js code to see if it's passing any sensitive data into wasm.


Js code is sufficiently dynamic where I wouldn’t be confident in anyone using this defense, even with a debugger open.


The complaint here is that moving from js to wasm means you can't tell if a package is maliciously exfiltrating your sensitive data. That presupposes that you can read and understand the js code. If your argument here is that you can't be confident in your ability to read and understand the js code, then moving to wasm is no longer a problem.


You can read the JS code.

If it's trying to be sneaky, you _cannot_ understand it, in general. If you think you can, that is false confidence that is best gotten rid of.


That’s probably true, but I do think that the addition of wasm complicated things. Imagine a js bridge that calls window objects by strings built in the wasm blob, or does anytning using eval. Now the wasm code can call anything js can through this bridge.


I suppose that's true, but you can also tell that the JS is trying to obfuscate what it's doing and just generally distrust it at that point.


Maybe the code wraps querySelector and getAttribute for wasm, or similar. Or maybe its underhanded code, designed to do something different than it seems to.


Thats neat, cool, given that, we are at least only as susceptible as we were before.


Wouldn't the network tab still record any network requests from wasm


I would assume so, but if the request is encrypted you wouldn't know what's in it.


>> the goal of WebAssembly is not to replace JavaScript, but to be an awesome tool to use with JavaScript.

Let's hope exactly the other way around will happen. I would rather like to see better interop between different languages using wasm than wasm + js.


I think that misses the point. Since WASM is a compile target you don't need JS to achieve interop between different languages if they are all compiled to WASM. The JS + WASM combo is to do things that WASM container cannot do on its own.


Also, JS is a more suitable target for most managed languages like clojure, typescript, elm, etc.


Well... two of 3 of the languages you provided as example were designed to be transpiled to javascript. I doubt JS is a more suitable target for other languages than an IR like wasm which is being designed to be a compiler target.


I would be interested in hearing a more detailed argument on why ClojureScript & Elm would be better if they targeted WebAssembly.

Even the WebAssembly authors seem to agree that it's not foremost a managed language compile target - The Overview text from http://webassembly.org/ says "Wasm is designed as a portable target for compilation of high-level languages like C/C++/Rust, enabling deployment on the web for client and server applications."


Elm was designed to be transpiled into javascript just like CoffeScript so let's put it aside for a moment. WASM is work in progress so I'm sure that if people care enough they can find solutions for such specific issues(i.e. seems that VM languages have their own set of issues). There is a GC proposal so managed languages will benefit a lot(i.e. smaller runtime).

JS is a high level language. I don't see many people compiling to managed languages outside of the browser. Wonder why is that? Few target JVM...but I don't see many(if any) compiling to Java, C#, Ruby or Lua or PHP. I've never seen anyone compiling JavaScript either unless they had to run it in a browser. This should tell you how good JS is when it has to compete on merit as compiler target.


Elm semantics is very far from JS - it's a kind of Haskell-lite. The tooling and diagnostics are very much custom and don't rely on JS developer tools or source maps. (Also, "transpile" is just another word for "compile")


Do you mean that Elm was not designed considering JS as its compilation target? Is Elm used anywhere else than the web browser? Why nobody compiles to JS outside the web browser if it's such a good compilation target?

>> Also, "transpile" is just another word for "compile"

Well, I prefer to use the "transpile" term when the target is a high level language.

JavaScript is a high level language. It seems some smart folks decided that a new "language/IR" is needed (wasm) so that people can use other languages on the web. Now let's make this new IR a first class citizen on the web.


I'm sure Elm design considered JS, but I'm also sure that if WebAssembly had been available when Elm was designed, it would still have targeted JS rather than WebAssembly. Same goes for ClojureScript.

WebAssembly is a refinement of asm.js, which started as a mechnism to enable C/C++ code to run in browsers. Other, managed languages aren't forced to go the asm.js route because their semantics aren't tightly married to a byte addressable, untyped program heap.


What exactly makes JavaScript a better target for languages such Elm (apart from GC and DOM access which are supposed to be implemented sooner or later) ? You realise that JavaScript itself is also compiled/transpiled by the browser engine(i.e. v8) before it executes, right?


Let me count the ways:

- code size - a runtime for a managed language is much bigger if you have to reimplement & ship the primitives you get from the JS platform.

- implementation complexity: a LLVM-webassembly-toolchain along with your own GC is much harder and more work than a JS backend, and would need to have a rather good payoff to be worth investing in.

- poor cross-browser development tooling support to have a good debugging experience

- GC implementation complexity and performance - firstly, there is no GC support currently and no timeline about when/if something materalizes. The current "future GC" support in webassembly[1] doesn't provide a GC implemnetation, just hooks to peacefully coexist with JS GC.

- JS interop

- browser support

Now, it may be that some of these get solved eventually - but they would all have to be solved, with high quality solutions, to beat JS as a managed language compile target.

[1] https://github.com/WebAssembly/reference-types/blob/master/p...


>> - implementation complexity: a LLVM-webassembly-toolchain along with your own GC is much harder and more work than a JS backend, and would need to have a rather good payoff to be worth investing in.

I strongly disagree. Wonder why no language(managed or unmanaged languages) designer uses this gem named JavaScript as compile target?(web stuff excluded)

It seems your whole argument revolves around the fact that JS has better support than WASM in browser. We already know this. WASM is a work in progress. It's not ready yet for prime time. This year we will get some managed languages compiled to WASM. Next year we might get GC. I believe in some distant future javascript will be compiled to wasm either by the client or by the browser itself(for backward compatibility). JavaScript is JIT-ed in the browser anyway.


you only need js to bootstrap wasm onto a canvas. then write the rest of your "site" in QT or GTK ;)


Is this possible already? I'd love to build web CRUDs using tcl/ttk for the GUI part


you could use emscripten to compile to wasm as a target https://kripken.github.io/emscripten-site/docs/compiling/Web...


>> I think that misses the point. Since WASM is a compile target you don't need JS to achieve interop between different languages if they are all compiled to WASM

Really? Can you please point me to some documentation about this? I can't mange to find out how to use a wasm compiled library (compiled from C) in C#/mono project (which also compiles to wasm )


If you manipulate the two code bases to be in the same module https://developer.mozilla.org/en-US/docs/WebAssembly/Underst.... Otherwise, export and import which is also covered on that page


> I would rather like to see better interop between different languages using wasm

Yes, and garbage collection that crosses language boundaries.


Is anyone even working on this? I don't remember seeing foreign function bindings in wasm other than for JavaScript.

If there are no competitors, JavaScript wins by default, just like C ffi did on server and desktop.


There’s a bunch of uses of wasm outside the browser. I’m personally not a huge fan of crypto currencies, but Etherium is looking to use it as a language for smart contracts, for example. Just like any small language, you can embed the interpreter into whatever and use it for scripting; the spec is written so that this is pretty easy.

That said, none of this means “replacing” JavaScript, no matter what the parent says. It’s a non-goal.


>> That said, none of this means “replacing” JavaScript, no matter what the parent says. It’s a non-goal.

I believe a better term would be "skipping" javascript than "replacing" javascript. There won't be many rewrites but I'm sure that many people would skip JS on new projects if they would have that option. Why would a Python, Go, Ruby developer choose JavaScript over Python given that their language of choice would compile to WASM(along with DOM/webAPI access)? The ecosystem may be a reason but that's only a matter of time(i.e. 1 -2 years).


One good reason is binary size; JS is going to have the advantage here since it’s runtime is already installed.

Another good reason is that, regardless of what you read on Reddit and Hacker News, a lot of people actually really like JavaScript.


>> One good reason is binary size; JS is going to have the advantage here since its runtime is already installed.

Yeah, that's true now though I don't think there is something that stops browsers to host a runtime(i.e. a pre-loaded std wasm library + wasm-gc) to help the languages compiled to wasm to reduce their compilation size. The question is really whether the browsers want to make WASM a first class citizen or not.

>> Another good reason is that, regardless of what you read on Reddit and Hacker News, a lot of people actually really like JavaScript.

I believe WASM could serve the other lot of people who are not that much into JavaScript. Using the same language on server and browser also reduces friction(i.e. see NodeJS). Personally I believe JS has a such rank based on reach not on merit.


There’s some complexity, but yeah they could do that. I really doubt it will happen; if we couldn’t get browsers to include jQuery, why would they do this? It’s even harder than that would be.

> reach not on merit

Node’s popularity and success is counter to this notion, IMHO. Seriously, lots of people love JavaScript.


I doubt many would pick JavaScript if given the option on the browser side.

Regarding node it has two things going for it, the frontend devs that only know JavaScript and try to do server side as well.

The fact that thanks to its world class JITs (V8 and ChakraCore) it easily beats Python and Ruby interpreters in performance, which are the most common deployed variant.


Let me see. A lazy developer that only knows Ruby compiles the entire Ruby interpreter into WASM just to run Ruby. Then the user clicks a button that does an API fetch and the whole browser freezes while it waits for the response. . . . Yeah not happening. WASM was built and meant for high performance low level languages, there is no way in Ruby and Python will make the cut.


That lazy developer will download a Ruby WASM based VM that someone else compiled for them.

Also the revival of Java, .NET, Flash, ActiveX is already brewing, this is not only about Python and Ruby.

Just doing games in Unity, compile to WASM and deploy, just like plain old Flash.

And while at it, use the 2D GUI to build a complete web site, just like plain old Flash.

The difference is now we can all be happy, because it is a Web standard.


You're just repeating the same thing as the parent. I don't think that's true. People legitimately love JavaScript.


>Using the same language on server and browser also reduces friction(i.e. see NodeJS). Personally I believe JS has a such rank based on reach not on merit.

And yet somehow thanks to NodeJS, javascript development seems to have gotten exponentially more complex.


Python and Ruby will never compile to WASM since they would need to have the entire interpreter compiled with it and it would be extremely slow and bloated experience. Not to mention those languages do not have very good support for async operations and the lack of closures make it a terrible idea for the web.


Yes, that was my thought too and I was disappointed to see them defending JS at the top of the article. Getting away from dynamic language mush is one of the biggest attractions I have to WASM.


You already got that from asm.js though.


why to use a half baked solution than something designed from the ground up for the job?


I don't read binaries so I don't particularly care how hackish the solution is as long as it works. There are benefits to wasm of course, but running C code in the browser isn't one of them.


Let's be real, the goal of WebAssembly is to replace JavaScript, but providing alternatives to it. The whole "WASM doesn't replace JS!" thing is pretty much just to placate the "But what's wrong with Javascript?!" crowd.


I disagree from a technical perspective. WASM is a box much like an iframe or a Java applet or Flash media. Therefore the things contained within that box are isolated from the things outside that box. JavaScript, on the other hand, operates outside that box and, with appropriate bindings, can interface with APIs inside that box.

The WASM will replace JavaScript argument exists not for any valid technology reasoning, because people desperately need it to (only for personal reasons) and don't understand how web technologies work on the front end.

The goal of WASM was never to replace JavaScript, but to replace Flash (before Adobe announced the death of Flash) in a language agnostic way.


I believe you are wrong. WASM has a text version and nothing stops you from using the DOM or the web APIs (given that wasm gets an API). What exactly is the black box? You can use OpenGL in javascript too if that's what you mean by "black box". You can't do anything new in wasm than in JS except you get better performance and more options (language wise).


Now imagine web sites written 100% in WASM, just like they were 100% in Flash.

What did you won with Flash being replaced?


Currently WASM can't access the DOM. But WASM-native DOM APIs are planned and then you will be able to completely ditch Javascript if you want.


Issues have been opened for native DOM bindings in WASM, but I am not sure if that work ever started. As others have mentioned there is the hosting bindings API that is well underway, which provides web APIs to the WASM container so that code compiled to WASM can interact with the JavaScript outside it. This doesn't sound like what you are hoping for though.

At this time, and for the foreseeable future, there are no plans with active code in development to implement WASM as a JavaScript replacement, at least to my knowledge.


Code compiled to WASM can already access Javascript outside it. Obviously. Otherwise how could it do anything at all??

> Issues have been opened for native DOM bindings in WASM, but I am not sure if that work ever started.

I didn't say work had started on it. I just said that it is planned. See here for proof: http://webassembly.org/docs/high-level-goals/

> access browser functionality through the same Web APIs that are accessible to JavaScript


> Otherwise how could it do anything at all??

By passing data.


Can you speculate on what these APIs will look like? JS is well suited for dealing with cross-browser incompatibilities because of its reflection support. That is much harder to build in a low-level target like WASM. COM is an example of what we might get, and that is not a pleasant prospect.


plenty of typed languages have reflection. i don’t see how this changes anything?


WASM is not a typed language. It is a language-agnostic compilation target.

So what would a DOM API exposed to WASM look like? COM is the only example that comes to mind.


> WASM is not a typed language. It is a language-agnostic compilation target.

These two things aren't contradictory. wasm is typed.


I'm dreaming of seeing a wasm DOM api that directly binds to the browser's apis, without passing through javascript.

Is this even a possibility?


That’s the “host bindings” proposal.

All of this tooling has been written to be forward-compatible with it, so whenever that lands, you can upgrade the tool and get a speed boost for free.


Great!


It's absolutely a possibility but the problem is one of speed. DOM interop is one of the things that slows down JS so much and requires a lot of flexibility.

Adding it to WASM will not be the amazing experience many think it will be.


I don't know about others but I'm not expecting it to be an amazing experience. It's more that I expect not having DOM interop to be an amazingly boring experience. Maybe Rust could be good for Web Workers but it'll be far more interesting when I can use it for interactions.

The overhead problem you mention reminds me a little of the false intuition that people have about databases.

I've worked on a couple projects where people were surprised that as the data set grew (either more customers, or accumulated customer activity), operations like INSERT and UPDATE got slower and slower, even without new functionality getting in the way. Everyone expects SELECT to get slower, but INSERTs seem to catch them off guard.

Every INSERT or UPDATE has to update the indexes. And when you quadruple the data, the update time for each index doubles. At first the cost of the insert is in the noise floor. It's swamped by the communication and transaction overhead. But after a handful of doublings it becomes detectable. A few more and it becomes noticeable. After a few more it becomes a problem, and if you haven't already changed your product roadmap, you do now.

To make a web page fast, you have to correlate the DOM with the CSS and the viewport. Adding more data isn't free.


Good illustration of that issue.

I don’t know if I agree it’ll be less interesting- but it will have narrower applications. They’ll be more self contained - data and processing related - rather than driving the UI... but I don’t know if I’d call that not interesting.

I mean... imagine a WASM game engine where the modules/plugins can be any language as long as the compile target is WASM and they follow the right API... with JS/DOM just doing the DOM part (canvas or webgl I guess).

Sounds pretty powerful and fun.


I believe that'd be a follow-up to the host bindings proposal [1].

[1] https://github.com/WebAssembly/host-bindings/blob/master/pro...


Thanks for the link!


It's proposed but it's also already possible if you use a very thin JS glue layer.


when we can make web pages, and entire sites without once actually using something a human can disassemble and reverse engineer ... this will be the end of the open web.

truly the complete dead end of it.

Unless maybe I'm missing something. Is a disassembler for WASM a thing yet?


I've tried to read source code from YouTube and let me tell you:

If that kills it, it was already dead. Obfuscation and minification is already as bad as bytecode. Honestly, wasm might be a little better because there are less insane hacks and more simple, if low level, code.

Also, if people are willing to implement DRM in it just because it's bytecode, I'd rather they did that than implemented rootkits in all of the browsers. Thanks for that one W3C.


The ability to preserve “view source” has been a first-class consideration of wasm since the beginning. It’s effectivly the same as JavaScript in this regard.


> when we can make web pages, and entire sites without once actually using something a human can disassemble and reverse engineer ... this will be the end of the open web. truly the complete dead end of it.

No more than it was when Flash was a thing, or Java applets, or Silverlight. The world has been presented with numerous opportunities to turn the web into nothing but binaries, it hasn't happened.

>Unless maybe I'm missing something.

You're missing the part where someone would have to put a gun to everyone's head and force them to rewrite the entire web as WASM blobs, then force all of the browsers to be redesigned, and the servers, so that HTML and plaintext are deprecated, for your doomsday scenario to be even remotely plausible.


I cannot disagree more. Sure, the days of "View Source" might be coming to an end (although I doubt it), but there has never, and I mean never been an easier time to get started with these things. The vast amount of tools and resources for learning available for free is unprecedented. The open web is quite safe for years, if not decades to come.


> Is a disassembler for WASM a thing yet?

Yes, it's part of the standard toolkit. See https://github.com/WebAssembly/wabt and specifically the "wasm2wat" tool.


Webpacked and possibly optimized/minified JavaScript is basically the same thing as compiled code. We are already there.


there's a human readable version, you can read more about it here: https://developer.mozilla.org/en-US/docs/WebAssembly/Underst...


It's great to see WASM taking off! In this context, see also Blazor, which runs C#/.NET code on WASM. https://github.com/aspnet/blazor


What’s the binary size like?

One interesting thing about wasm is the difference between libraries and apps; Rust’s small binary size here can make it useful for this infrastructure work, but for languages that need to bring along the runtime, it’s much more complex. This is one reason why we’re pursuing stuff like wasm-pack.

I’m glad to see more and more languages compiling to wasm though! Exciting times.


> What’s the binary size like?

I asked this same question[0]. Appears mono.js is 166kb in release mode, but it downloads/uses the DLLs directly as a system would, so those sizes are the same as they are for desktop apps (not sure off the top of my head what that is for ASP.Net stuff or the stdlib).

0 - https://github.com/mono/mono/issues/7820


Ah nice, thank you! The recent work with emscripten to get sizes down will help them too, I’m sure.


The original Blazer was based on the DotNetAnywhere runtime and the binary size was actually very reasonable.

Now that they're using the Mono runtime it's significantly larger and it seems their main task now is finding ways to remove unused code from that runtime to get it back to reasonable.


The original runtime was about 60kb in size, that's still unreasonable to add to a library. Imagine a small library like Redux (2kb, including dependencies) having to ship with a runtime that's 60kb (or more). Now imagine a project that depends on multiple libraries of the same size or larger... This is why a language that has no runtime (such as Rust) makes more sense for developing wasm packages that can be used side-by-side with other languages.


>The original runtime was about 60kb in size, that's still unreasonable to add to a library

What? What kind of bubble are you working in?


Web applications nowadays depend on hundreds of dependencies. If each one of these dependencies were to have a size of 60kb or more that would be very bad.


>The original runtime was about 60kb in size, that's still unreasonable to add to a library.

In which planet? Not only will most frameworks and standard JS libs dwarf this, but the average web page size has upped to ~ 3MB these days...


>Not only will most frameworks and standard JS libs dwarf this

The original runtime that was used by Blazor was already a compact .NET runtime, and no matter how much you minify it (or any other runtime, such as the JVM), it will always have a considerable size.

>the average web page size has upped to ~ 3MB these days...

This is not an excuse to make web pages' sizes even larger :).

Btw, I'm not against the idea of using a managed language that targets WebAssembly for front-end development. On the contrary, I'm very excited about Blazor and I'm following its development, and I would love to see similar frameworks for other languages such as Kotlin or Swift.

But while I think the size of a runtime won't be an issue for web applications that use such frameworks, I don't like the idea of shipping large runtimes with wasm packages that might be used with other languages.


There is an idea that the runtime could be hosted from a common CDN and then cached by the browser across applications so you only have to download the runtime once. Combined with browsers caching the compiled versions of the wasm modules, the cost of the large runtime might be pretty minimal in practice.


That was tried and failed already with JavaScript libraries.

Look at something like jQuery. Let's assume for the sake of discussion there are 50 versions of jQuery (that's a low estimate), and 6 majorly used CDNs. That's 300 distinct cachable items. Now add in that most people now use multiple devices, and that caches are generally completely full and evicting things constantly. The chances of having a specific version from a specific CDN on the specific device is actually pretty low.

Now multiply that whole thing by another 100 libraries that all want to be the next jQuery. It's just not going to happen.

And cross-domain or content based caching isn't a solution either as it's opens an extremely large security hole (basically being able to probe your cache checking if a specific hash or content exists in it).

I'd much rather spend our collective time improving dead code removal tools and optimizing tightly linked bundles of libraries to give each web application it's own customized, small, optimized, and easily cachable "bundle". It avoids the reliance on 3rd party CDNs, it gives control over caching behavior back to the original website, it improves security, and can be faster (both in download speed and runtime speed).


It should be noted, I believe this is currently more of an interpreter than AOT-compiled like LLVM bitcode is. Mono is compiled via WASM that then interprets CIL DLLs.


This is great. Wasm really seems to be picking up steam. Any examples of a Rust crate that has already been published to the npm registry?


Ashley and I ran a workshop at BoosterConf a monthish ago using this tooling, a bunch of people used it to publish demo packages. This is effectively a release announcement, so we don’t have anything super real yet that I know of. There’s some stuff in the works though.

(You can see those here: https://www.npmjs.com/search?q=hello-wasm)


In its wasm-rewrite, the source-map module acquired a destructor that must be manually invoked by its clients [1]. This makes the API much worse. Is this typical of JS APIs that use wasm?

1: https://github.com/mozilla/source-map#sourcemapconsumerproto...


Yes, the gc isn't exposed yet, so neither JS nor wasm are notified when an object goes out of scope (which would allow to reclaim the memory on the wasm side). It's on the roadmap, so it should eventually come.


This is indeed a problem for Wasm/JS integration. The JS WeakRef proposal[1] will address it for many use cases, and the WebAssembly GC proposal[2], combined with JS Typed Objects[3] will address many others. Even before those features will be available, I'd expect the community to iterate on patterns to make APIs nicer.

[1] https://github.com/tc39/proposal-weakrefs [2] https://github.com/WebAssembly/meetings/blob/master/2018/pre... [3] https://github.com/tschneidereit/typed-objects-explainer


It's been really exiciting to follow all the awesome work that Mozilla and the Rust team are doing in this area. I'm looking forward to this bright new Rust WASM future for sure!


Does any of this tooling (I.e. wasm-pack, wasm-bindgen) work with the wasm32-unknown-emscripten target? All of the examples I see use wasm32-unknown-unknown, which is (I think) of limited use to me since I'm linking a fairly complex chain of native libraries against my current wasm target.

It seems like cargo-web has lots of this ground covered already. I'm wondering why build these other tools in that case? I don't have a dog in this fight, I'm just working on a wasm-based app that I'm hoping will serve me for quite some time, and seeing what appears to be duplicated effort at such an early stage worries me a bit.

Either way, thanks for building this!


We’re focusing on the unknown target for basically all future work; this stuff can work with the emacripten target, but it might take some PRs to configure it, etc. We’d be open to people hacking on such a thing, but it’s not where the team is putting in any effort.


Got it. I assume the unknown target will never be able to link against native libraries beyond those provided by Rust's core itself? I assume the answer is no, but a few years ago I assumed I wouldn't ever be able to do what wasm is letting me now, so I don't want to hold too tightly to those assumptions. :)


By “native libraries” you mean “C libraries”?

If so, then that’s correct, as rustc can’t compile C code. You need a C -> wasm compiler, and that’s emscripten.

Hopefully we’ll have built the ecosystem enough that you won’t need to rely on those libraries :)


Unless I'm misunderstanding, this sounds like a mistake to me. On any other platform, Rust interoperates smoothly with C libraries and does not demand purity. There's lots of existing code written in C, and expecting all of it to be replaced with pure Rust libraries is unrealistic.

Also, doesn't clang also have a wasm backend now? Emscripten isn't the only option.


It's because this is all a little more complex than that.

Clang does have a wasm backend, same as the unknown target. It suffers the same problems; that is, one of the things that emscripten does is provide a runtime/support code that does things like "automatically translate opengl to webgl". That is, one of emscripten's major goals is "get code that was never assumed to be able to run on the web to run on the web with as little hassle as possible." Outside of the web, those C libraries were very much intended to work on the native platform. So there's extra complexity there.

We continue to support emscripten for when you need this use-case, but it effectively only works if you're building an application, not a library, and we want to support people writing libraries.


Are there any benchmarks comparing WASM with Neon on Node.js?


Generally should be faster, it we haven’t made benchmarks. Lots of wasm is client side, Neon is server side. Wasm on the server is coming along too. It’s probably something worth putting together!


ah so it isnt in node yet?


It is! It’s in the latest LTS even. But in my understanding, it hasn’t been a focus of node, and so sometimes stuff breaks, etc. It’ll get there! Certainly exciting as well.


I'm kind of curious how wasm is going to work out. It seems only logical that wasm interpreters will be optimizing JITs. Wasm will essentially be an intermediate language similar to JVM bytecode.

At that point why not just use the JVM stripped of the useless stuff as a base and add the remaining small pieces that might be needed. Or Graal.

I guess I don't understand what Wasm is doing that is so much different that couldn't be handled with other more advanced code bases.


> It seems only logical that wasm interpreters will be optimizing JITs. Wasm will essentially be an intermediate language similar to JVM bytecode.

Yup

> why not just use the JVM stripped of the useless stuff as a base

This often comes up in WASM discussions. First of all, you cannot divorce a JVM from its useless stuff. Many parts of the stdlib might as well be part of the bytecode (e.g. strings which then carries a done of charset code, classloaders, boxed primitives, method handles, lambda factories, etc). I would love to see an effort to leverage JVMs bytecode without all of it's baggage, but for now the marriage is so tight they are inseparable.

> Or Graal

That's a runtime VM/compiler, not a bytecode spec to target.

> I guess I don't understand what Wasm is doing that is so much different that couldn't be handled with other more advanced code bases.

Keep it simple, (mostly) no undefined behavior, no required GC, works the same on all platforms, large test suite, multiple big-company backers, etc. I can't think of an "assembly set" (or bytecode) that does all of that.


> It seems only logical that wasm interpreters will be optimizing JITs.

Webassembly was designed not to do this, and I really hope it stays that way forever. Optimizing JITs are useful for highly dynamic languages like Javascript; Webassembly's fast startup times and predictable performance are a much better solution for languages like Rust.

> I guess I don't understand what Wasm is doing that is so much different that couldn't be handled with other more advanced code bases.

On top of "the vast majority of the optimization is done ahead of time so there's no need for a JIT," there's also the memory model. Webassembly exposes memory as a big array of bytes for you to manage yourself, just like hardware. The JVM enforces a particular object model with classes, inheritance, and garbage collection.

So I guess what I'm saying is that "the JVM stripped of all the useless stuff" is what Webassembly is already. And some of the stuff that got stripped is the JIT and object model.


> Webassembly was designed not to do this, and I really hope it stays that way forever. Optimizing JITs are useful for highly dynamic languages like Javascript; Webassembly's fast startup times and predictable performance are a much better solution for languages like Rust.

WebAssembly is a VM bytecode for a stack-based VM. Unless you want things to run very, very slowly you still need a JIT to emit native code, rather than loop dispatching each WebAssembly instruction in a bytecode interpreter.

WebKit, for example, has a two-tier JIT for WebAssembly just like JS, but WebAssembly has already had all the high level language related optimizations performed and looks a bit like an intermediate representation anyway so the first pass is very fast.


Yes, I do want a JIT in that sense. I just don't want it doing Javascript-style optimizations with profiling and speculation+deoptimization.

What WebKit is doing is moving in that direction (unfortunately) but it still looks much more like an "-O0 -> -O3" sort of thing than what Javascript gets.


So that means wasm has already been inlined and loops unrolled? How will this all interact with vectorization or insurrection choice?

I think the VM is going to need to be just like every other VM (once inlining is introduced, why even bother with trying to optimize wasm before the JIT).

If wasm is going to be so good, then you could retart java to it? I know a lot of high performance java shops that would love to get rid of the GC in Java. But Hotspot can be an optimizing beast.


You can't get rid of GC in Java without essentially replacing Java.


Can you use JS packages as dependencies?


From the article:

> The next large piece of development work on wasm-pack will focus on using custom segments in compiled WebAssembly to declare dependencies on local Javascript files or other npm packages.

> The preliminary work for this feature has already landed in wasm-bindgen, so the next step will be integrating it into wasm-pack.


"WebAssembly is not to replace JavaScript, but to be an awesome tool to use with JavaScript."

NO, Replace Javascript, replace HTML, replace CSS.


[flagged]


What makes you say so? JavaScript in itself is not a bad language at all, and many programmers genuinely like it.


It's not a bad language in itself, no - it's just a waste of resources for the end-user, and in general it's being marketed to newcomers as the language they should learn by default - leading to a tonne of unoptimized sites and terrible applications using it.

Then again, I suppose that's a fault of the type of programmers attracted to it than it is the language itself.


If you find yourself typing something about "the type of programmers attracted to X language" just delete what you wrote and move on.

JavaScript isn't going anywhere. End-users don't care about executing "non optimal code."


> If you find yourself typing something about "the type of programmers attracted to X language" just delete what you wrote and move on.

I wouldn't say that's the right way to go about it or to think, especially in the case of JavaScript - more than ever, it's being taken up by people with no passion or desire to program solely so they can make what they think is going to be "The Next [WebCompany]," it's something that doesn't particularly have a parallel with any other language.

> End-users don't care about executing "non optimal code."

They do when the window freezes, or their Electron app locks and crashes, or when they suddenly can't have their browser running in the background while they're playing a video game.


> more than ever, it's being taken up by people with no passion or desire to program solely so they can make what they think is going to be "The Next [WebCompany],"

See, that's why you were encouraged to stop before you dug yourself deeper. Now you've doubled down on disparaging an entire class of people based on their choice of programming language because of some assumed greed you think they think they have.

Perhaps people are taking up Javascript because it is, bar none, the easiest language to play around with. Every modern computer either ships with a browser installed, and the vast majority of them, excluding mobile platforms, allow for someone to easily open a Javascript development environment not just to start something new, but to tinker around with the web page they are looking at.

Of course there will be horrible and crappy Javascript programs and libraries released to the wild. That's the same whenever there's a large influx or new people to the programming ecosystem and a language that's fairly easy to use but has some edge cases. Just look at Perl, and the CGIs of the late 1990's and early 2000's. A very large part of Perl's current reputation is because of people that weren't the best programmers (because they were new) being able to whip out little programs to do what they want, but also not entirely understanding some of the deeper intricacies of Perl or some better programming practices in general.


A great comment, and I couldn't agree more. If the family computer in the early 90s didn't have QBasic - I wouldn't be a developer today.

> more than ever, it's being taken up by people with no passion or desire to program solely so they can make what they think is going to be "The Next [WebCompany],"

I feel like kbenson forgets that the point of programming to the vast majority of people, is typically the end result.


> I feel like kbenson forgets that the point of programming to the vast majority of people, is typically the end result.

Sure it is. I just think most people don't start out thinking "I'm going to make the next Facebook", or at least not seriously. A lot of the time it's just tinkering. I mean, that's the reason the code produced isn't high quality, because the people really are complete amateurs screwing around. In that respect, I think the end result is "I want to learn this or to make something cool".


> End-users don't care about executing "non optimal code."

I seem to remember Java Applets & Java "Web start" (or pretty much any browser "plug-in" runtime) causing a fair bit of grief for end-users...


> it's just a waste of resources for the end-user

Frankly, it's not a problem of the language, but the browser. As far as I can tell, none of the popular browsers offer a way to limit resource usage, even though users would clearly benefit from it.


That actually would be a productive way of solving the problem, if limitedly. That'd make me fall much more into the neutral camp on it.


I don't think it ever happens though. Browser vendors focus on performance, and any of these limits would mean degraded experience from the point of the view of the user.


What I take issue with is the lack of options in a critical domain and our complacency with that.

Maybe we won't replace Javascript, but we should definitely have more language options client-side that don't require Javascript-glue to interface with the DOM.


You are living in the past tbh. There are tools which make augment the language and it is literally taking over the world now!


It focuses on the lowest common denominator of programmers, and in general the community around it doesn't really care to optimize it or teach the people they attract towards good programming standards.


This is simply not true. There are plenty of beginner-level JavaScript tutorials and resources out there, but the same could be said of any language. JavaScript libraries du jour like React and Angular are certainly not aimed at beginners, nor are popular tools of the trade such as Webpack and Babel. The focus is on allowing experienced developers to create production-ready web applications, which is exactly where it ought to be.

I’ve been programming in JavaScript for nearly 15 years now, though, and there has been a near-constant push from the community toward better programming practices during that time. Given how far the language has come just in the past 5 years, I’d say they’ve been pretty successful in that regard.


JavaScript has a low barrier of entry, sure. That doesn't equate to the language being incompetent though. Every language has its incompetent developers. With Node.js you can perform some incredible systems automation cross-OS and it performs extremely efficiently.


Let's just hope the world doesn't depend on left-pad.


Meh. JavaScript is literally the PHP of programming language...


So, yet another single purpose package manager. FFS...


This isn’t a package manager. It’s tooling to create npm packages.




Applications are open for YC Summer 2019

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact

Search: