Some people somehow misunderstood WebAssembly. There are those who believe that once browsers already support WebAssembly execution (since 2017), then everything is ready. Not even close yet, only MVP is ready (minimally viable product). I can guess where this error comes from: after the release of MVP, its developers have promised to maintain backward compatibility at the level of “any code written now
will work in the future.” But this does not mean that the development of WebAssembly is completed, not at all! Many features are being developed right now and are planned for development in the near future. And when they are implemented - everything will change very much.
All these features you can try to imagine in the form of a tree of skills in any game. We have a couple of “basic” (already implemented features) and a whole tree with a lot of branches and leaves that will eventually open, giving us more and more power.

Let's look at what we already have now and what we still have to open.
(
Under the cat a lot of pictures, traffic )
Minimally Viable Product (MVP)

At the very beginning of the creation of WebAssembly is
Emscripten , which made it possible to compile C ++ code into JavaScript code. This made it possible to transfer to the world of the web a large number of C ++ libraries, without which the launch of higher-level code would be impossible. The generated JS code was far from ideal and worked slowly (compared to its native version). But still, Mozilla engineers found a couple of ways
to make it faster. The main one was the selection of a subset of the language that could be performed at speeds comparable to the speeds of native code execution. This subset was called
asm.js.Developers of other browsers noticed and appreciated the speed of asm.js, all major browsers
received support for it. But this was not the end of the story. This was just the beginning. There were still opportunities to work faster. But they have already gone beyond Javascript. It turned out that the native code (for example, in C ++) needed to be compiled not into Javascript, but into something else. In something new, created specifically as a quick alternative to JS. And so it appeared WebAssembly.
')
What is included in the first version of WebAssembly? What was enough to get the proud title of "minimally viable product"?
Skill: target compiler platform

The programmers who worked on WebAssembly understood that their task was not to support C or C ++ alone. The task was to enable compiling code in any language in WebAssembly. This was supposed to be such an “assembler” that should be executed in the browser, just like the computer code of the desktop application is executed, for example, on the x86 platform. But this new language should not rely on any specific platform; its goal should be a higher level abstract platform, the concrete implementations of which would already depend on the instruction set used on this hardware.
Skill: fast code execution

Everything had to work fast. Otherwise, why bother to plot this whole story? In the end, the user should be able to run really “heavy” applications, be able to play top games in the browser, etc.
Skill: compactness

It is important not only the speed of the code, but also the speed of its loading. Users are accustomed to desktop applications that run very quickly (after all, they are installed locally and have all the necessary resources at hand). Web applications also run relatively quickly, because they do not load so many resources at once. And this gives us a new task: if we want to create a new type of web application with a code base as large as the classic desktop, but downloadable from the Internet, the code should be as compact as possible.
Skill: memory access

Our new applications will also need to work with memory a little differently than JavaScript code does. Need direct access to memory blocks. This is due to the peculiarity of the work of languages C and C ++, in which there are pointers. A pointer is, roughly speaking, a variable that contains an address in memory. An application can read the data at this address, change it, and even use pointer arithmetic to “walk” through memory forward from the specified address. A huge amount of code in C / C ++ uses pointers to improve the efficiency of its work, creating a target platform for such code is impossible without the support of pointers.
But we cannot allow a piece of code downloaded from the Internet to have direct access to the memory of our process - this is too dangerous. We will have to create an environment that, on the one hand, allows native code compiled in WebAssembly to believe that it has direct memory access, but on the other, to strictly restrict the area in which it is allowed to manipulate data.
For this, WebAssembly uses a “linear memory model”. This is implemented using TypedArrays - something like an array in JavaScript, but containing only a sequential set of bytes in memory. When you want to put something in it, you use the access to the element by index (which can be an address in memory). Thus, this array "pretends" as a block of memory for C ++ code.
New achievement!
So, with all of the above, people will finally be able to launch a desktop application in a browser with about the same performance as if it were native. That's about this set of features and was called the “minimally viable product” (MVP).

At this stage, some applications really could already be built for WebAssembly and earn in the browser. But there was still a long way ahead.
Heavyweight desktop applications

The next important step should be the ability to run really large desktop applications. Do you already have a full version of Photoshop running in a browser? And you did not install it, just opened the link - and now you are 100% full of the power of this product, at native speed, the latest version with all updates and patches, on any device.
And we are not so far from this - examples are already beginning to appear. For example, AutoCAD. And also Adobe Lightroom. But let's be frank - not everything is still ready in the current implementation of WebAssembly to run truly large applications. Bottlenecks are examined and corrected right here at the moment when you are reading this article.
Skill: multithreading

Obviously, we need multithreading. Modern computers have many cores. We need to be able to use them.
Skill: SIMD

In addition to multi-threading, there is another technology that allows for more efficient implementation of parallel data processing. This is SIMD: processing one instruction of several data blocks at once. An important aspect for a really fast WebAssembly operation.
Skill: 64-bit addressing

Another important feature of modern hardware architecture, which is not yet present in WebAssembly, is support for 64-bit memory addressing. Everything is simple: with 32-bit addresses you can use only 4 GB of memory (which is very small for large programs), but with 64-bit addresses - already up to 16 exabytes (this is very much for modern software). Of course, not only the theoretical maximum is important, but also practical (how much memory the OS will give you). But on most modern devices already 4 or more GB of RAM and this number will grow.
Skill: streaming compilation

We need not only to quickly execute applications. We also need to reduce the time lag between the start of its download over the network and its start. Stream compilation allows you to start processing a WebAssembly file even before it is completely loaded. We parse the instructions on how they are loaded over the network. Thus loading and compilation go in parallel. In the Firefox code, we managed to achieve a compilation speed
higher than the download speed — that is, the processing time of some N-byte code turned out to be less than the loading time of this code over the network. Other browser developers are also working on streaming compilation.

A thing related to streaming compilation is using
two compilers . One of them (above) works quickly and allows you to immediately run the downloaded code. He, however, does not perform all of his theoretically possible optimizations, since it takes more time. Such optimizations are performed by another compiler running in the background. As soon as he finishes his work, one version in memory replaces the other and then works instead of it.
So we get a quick start of the application, and its effective work.
Skill: caching

If we have once downloaded and compiled some WebAssembly code with an optimizing compiler, then it does not make sense to do the same when loading this code in another tab (or the next time you open the browser, provided the application remains unchanged). Compiled code can (and should) be cached and then used from the cache.
Skill: other improvements

Now there are a lot of discussions about what other improvements are possible and what the efforts of the developers should be focused on. Something will definitely be implemented, something will not immediately, something will not at all. I, with your permission, will identify all these points in the general class “other improvements”, and what will be included in it will be understood over time.
Where are we now?
Somewhere around here:

Multithreading
For multithreading, we have an almost complete
plan , but one of its key parts (
SharedArrayBuffers ) was forced
off at the beginning of this year. It will be turned on soon and we can continue.
SIMD
Actively
developed right now.
64-bit addressing
For
wasm-64 , we have a fairly clear idea of how everything should work. We were based on the approaches of x86 and ARM architectures.
Stream compilation
In Firefox, it was
added back in 2017, other browsers are working on it.
Using two compilers
In Firefox, this was added back in 2017, and in other browsers in 2018.
Implicit HTTP caching
In Firefox, development is
almost complete , there will be a release soon.
Other improvements
There is a discussion
As you can see, most of the items are still under active development. And nevertheless, we can already see applications running on WebAssembly today, since there are already enough opportunities for someone else. As soon as all the above features are ready - we will open another “new achievement” and even more new applications will receive support for WebAssembly.

Javascript Interaction

WebAssembly was created not only as a platform for games and heavyweight applications. It can be used for regular web development. We realize that today there are very large web applications written in Javascript and very few people will decide to take and completely rewrite them to WebAssembly. The important point here is that it is not needed. Most likely, most of these applications work quite well and only in some bottlenecks, there may be a lack of performance in calculations, or throughput of data processing, or lack of functionality due to the lack of a JS version of some library. We want to give developers the opportunity to rewrite only these “bottlenecks” in WebAssembly, leaving the rest of the code in the usual JS. And this is already possible. For example, by rewriting the Gutenberg parser on Rust and gathering it under WebAssebly, we managed to achieve a performance increase of
86 times .
But in order to make such a practice mass and comfortable, we need to implement something else.
Skill: quick calls between JS and WebAssembly

Calling a WebAssembly from JS should work very quickly. By adding a small WebAssembly module, the programmer should not feel any performance loss, even if this module is called very often. This is not the case in MVP (since the goal of MVP was not to maximize the performance of such calls). This problem has yet to be fixed. In Firefox, we have already ensured that some JS-> WebAssembly calls are
already faster than non-line JS-> JS calls . The developers of other browsers are also working on this task.
Skill: fast data exchange

This task is related to the previous one: it is important not only to quickly call the WebAssembly code from JS, but also to quickly transfer data between them. There are certain problems with this. For example, the fact that WebAssembly understands only numbers. There are no objects in it, but they are in JS. So, we need some kind of broadcast layer. It already exists, but is not yet productive.
Skill: integration with ES modules

Now using a WebAssembly module looks like a special API call that will return a module for you to use. But this means that a WebAsse assembly is not really part of the JS module graph of a web application. To have all the functions available to the ES module (such as export and import), the WebAssembly module must be able to integrate with the ES modules.
Skill: integration into development

Just to be able to import and export - does not mean yet to become a full-featured module. We need a place where WebAsse modules could be distributed. What will be analog of npm for WebAssembly? Hmm ... what about the npm itself? And what will be the equivalent of a webpack or Parcel for WebAssembly? Hmm ... how about webpack and parcel?
WebAssembly modules should not be different from regular modules, which means they can be distributed through the same infrastructure. But we need tools for their integration into this infrastructure.
Skill: Backward Compatibility

There is one more important thing that we must provide. Everything should work well even in older versions of browsers. Even in those that have no clue about WebAssembly. We have to guarantee that by writing once the code for WebAssembly, the developer will not have to write the second version of that same code in Javascript simply because the site must open in IE11 too.
Where are we now?
Somewhere here:

Quick calls between JS and WebAssembly
Already
implemented in Firefox, is working in other browsers.
Fast data exchange
There are several suggestions. For example, extend the type system in WebAssembly with references to JS objects. This is possible, but will cause the need to write additional code (for example, to call JS methods), which does not work too fast. To solve this problem, in turn, there are also several suggestions.
There is one more aspect concerning data exchange. This includes tracking how long data can be stored in memory. If you have any data in memory that the JS code should have access to, then you should leave it there until the JS code reads it. But if you leave them there forever, then we will get a memory leak. How to know that data can already be deleted (JS-code has already read them)? To date, this responsibility lies with the programmer - everything is released manually. As soon as the JS code has finished reading the data, it should call something like the “free” function. But this approach is morally obsolete and often leads to mistakes. To solve this problem, we introduced the concept of
WeakRef in Javascript. This makes it possible to read the data on the side of the JS code, and when the garbage collector is triggered, it is possible to correctly clear the memory in the WebAssembly module.
All this is still in development. Meanwhile, in the Rust ecosystem
, tools were
created that automate the writing of such code for you, replacing the parts that have not yet been implemented with their own implementation. One of these tools deserves special mention. It is called
wasm-bindgen . When he notices that your code on Rust is trying to get or return JS objects or DOM objects - it automatically creates a JS layer that will be able to interact with your Rust code. This layer can also interact with the WebAssembly module written in any other language, so not only Rust programmers can use this tool.
Integration with ES-modules
The plan of work in this area has been around for quite some time. We are actively working on it in conjunction with the developers of other browsers.
Development integration
Already, there are tools like the
wasm-pack in the Rust ecosystem, allowing you to automatically pack everything you need for release into npm. And there are people using this tool to create their own modules.
backward compatibility
For backward compatibility, we have the wasm2js tool. It allows you to turn a wasm file into an equivalent .js file. This Javascript code will not be fast, but it will work on any browser (including one that does not support WebAssembly).
As you see, we are very close to receiving this “achievement”. And as soon as we do this, the path will open to two more.

JS frameworks and JS compiled languages
The first of these is the ability to rewrite popular heavyweight JS frameworks on WebAssebly.

The second is to enable programming languages that compile into Javascript to replace it with WebAssembly. We are talking about languages like
Scala.js ,
Reason ,
Elm .

For both of these tasks, WebAssembly must support a number of new high-level features.
Skill: garbage collector

We need integration with the browser garbage collector for a variety of reasons. First, recall the task of rewriting JS frameworks (or their parts). This may be necessary. For example, in React we have an algorithm for comparing DOM-trees, which can be rewritten to Rust with effective multithreading. We can also speed up something better by allocating and freeing memory. In a virtual DOM, instead of creating a set of small objects that the garbage collector would later need to track and delete, one could use a special memory allocation scheme. For example, allocate a block of memory at once, place all objects in it, and then delete it with one call. This will both speed up code execution and save memory.
But we also have to constantly interact with the JS-code. You can't just copy data back and forth all the time, it will be inefficient. So, you need to be able to integrate with the garbage collector running in the browser in order to be able to work with objects whose lifetime is determined by the Javascript virtual machine. Some JS objects will need to refer to linear memory blocks created in WebAssembly modules, and some linear memory blocks will contain references to JS objects.
If at the same time cycles are created (and they will be), then this will create problems for the garbage collector. He will not be able to determine what else is used and what is no longer. WebAssembly needs tighter integration with the browser's garbage collector to avoid this.
It will also help languages such as Scala.js, Reason, Kotlin and Elm - they can be compiled into Javascript, which means they use its garbage collector. If WebAssembly will use it, it means that the code in these languages can be compiled for WebAssembly and should not notice any difference in terms of the nuances of the garbage collector (it will be the same).
Skill: exception handling

We need exception handling. Yes, some languages, like Rust, do not use exceptions. But many others use it. At the moment, you can replace exception handling with a code with no exceptions - but it works slowly. Thus, now when developing for WebAssembly, it is better not to use exceptions initially.
In addition, there are exceptions in Javascript. Even if you don’t use them in your code, some standard function can throw it away and you need to do something about it. If your WebAssembly-code will cause a JS-code, and that will throw an exception - we cannot process it correctly. The code on Rust, for example, will simply crash. This needs to be changed, we need a normally working exception handling script.
Skill: debugging

Another thing that JS developers are used to is good debugging tools. All modern browsers have tools for convenient analysis of Javascript code. We need the same level of support for WebAssembly.
Skill: tail calls

To support functional languages, we need a thing called
tail calls . I will not delve into this topic, somewhat simplifying it can be said that the tail call is a way in some cases to call a function without allocating a frame for it in the stack. Since this feature is crucial for functional languages, we want to have its support in WebAssembly.
Where are we now?
Somewhere here:

Garbage collection
To implement garbage collection, there is currently work in two directions: it is
Typed Objects for JS and, in fact,
the garbage collector for WebAssembly . Typed Objects will allow to describe the clear structure of the object. There is already a vision of how this should work, and it will be discussed at the upcoming TC39 meeting. Accordingly, the GC for WebAssembly will be able to access the above structure for its own purposes. Work is already underway on its implementation.
As soon as both parts are completed, we will get a system from interacting JS and WebAssembly, which is able to understand at all levels what the object consists of and effectively use its internal data. We already have a working prototype. The prototype, however, cannot simply be taken and released - we have to spend some time on standardization and editing. We expect that it will come to release somewhere in the 2019th year.
Exception Handling
Work on
exceptions is now at the research and development stage. , , .
Debugging
Firefox. . , . , .
.
.
— , «JS- JS »

, «» . ?
, « ». - , ? «» «WebAssembly». HTML, CSS JavaScript — .

, , . — . .

. - . , . - — , . , . , , , «» -: , , ..
.
-, ? - , — . - , Windows, . . — .

. , . , . ? - . - . , , - , .

, «»: . , . HTML, CSS Javascript? , WebAssembly.
, WebAssembly « , ». .

.

Node.js

WebAssembly Node? .
Node , Javascript. , JS- JS-, . Node . , Node.
, . , : , .
, WebAssembly, . , , Javascript-. .
Node . Node- Linux Windows — - . WebAssembly- ( ). ( ) Node , — Node. , WebAssembly- — . -
POSIX - ( , ).
:

, Node- WebAssembly-? - . . , Node , -. WebAssembly- — . - «POSIX WebAssembly». PWSIX (portable WebAssembly system interface)?
?
, . , , Nod ( ). , .

- . , .

CDN, Serverless, Edge Computing

, CDN, Serverless, Edge Computing. , , . WebAssembly?
. — ( ) . . JS (SpiderMonkey V8) - , . WebAssembly — .
, ?
:

. WebAssembly (
Cranelift ) — . — - , - . , Fastly, . — , . , — .
?
- :

. , . ,
WAVM wasmjit.
, Cranelift, wasmtime. - , , , , …

WebAssembly , . (
, ), WebAssembly- . , , , .

« » ( / « »). JS-, WebAssembly — . Cranelift wasmtime , - . WebAssembly . — IoT- . WebAssembly — .
findings
« ».

, WebAssembly . — . , MVP . - WebAssembly . — , JS- « », . — . , , . , : , , , — .
WebAssembly . .