Einige Leute haben WebAssembly irgendwie falsch verstanden. Es gibt Leute, die glauben, dass alles bereit ist, da Browser WebAssembly bereits unterstützen (seit 2017). Noch nicht einmal in der Nähe, nur MVP (minimal lebensfähiges Produkt) ist bereit. Ich kann mir vorstellen, woher die Wurzel dieses Fehlers stammt: Nach der MVP-Veröffentlichung versprachen die Entwickler, die Abwärtskompatibilität auf der Ebene von "Jeder jetzt geschriebene Code
wird in Zukunft funktionieren" beizubehalten. Dies bedeutet jedoch nicht, dass die Entwicklung von WebAssembly abgeschlossen ist, überhaupt nicht! Viele Funktionen werden derzeit entwickelt und sind für die nahe Zukunft geplant. Und wenn sie implementiert werden, wird sich alles sehr ändern.
Sie können versuchen, sich all diese Funktionen in einem Spiel in Form eines Fähigkeitsbaums vorzustellen. Wir haben ein paar „grundlegende“ (bereits implementierte Funktionen) und einen ganzen Baum mit vielen Zweigen und Blättern, die sich im Laufe der Zeit öffnen und uns immer mehr Kraft geben.

Schauen wir uns an, was wir jetzt schon haben und was wir noch entdecken müssen.
(
Unter dem Schnitt viele Bilder, Verkehr )
Minimum Viable Product (MVP)

Ganz am Anfang der Geschichte von WebAssembly steht
Emscripten , mit dem C ++ - Code in JavaScript-Code kompiliert werden konnte. Dies ermöglichte es uns, eine große Anzahl von C ++ - Bibliotheken in die Welt des Webs zu übertragen, ohne die es unmöglich wäre, Code auf höherer Ebene auszuführen. Der generierte JS-Code war alles andere als ideal und arbeitete langsam (im Vergleich zu seiner nativen Version). Trotzdem haben die Mozilla-Ingenieure einige Möglichkeiten gefunden
, um es schneller
zu machen . Die wichtigste war die Zuweisung einer Teilmenge der Sprache, die mit Geschwindigkeiten ausgeführt werden konnte, die mit den Ausführungsgeschwindigkeiten des nativen Codes vergleichbar waren. Diese Teilmenge wurde
asm.js genannt.Entwickler anderer Browser bemerkten und schätzten die Geschwindigkeit von asm.js, alle gängigen Browser
erhielten ihre Unterstützung. Aber das hat die Geschichte nicht beendet. Das war erst der Anfang. Es gab immer noch Raum, um schneller zu arbeiten. Aber sie gingen bereits über Javascript hinaus. Es stellte sich heraus, dass der native Code (zum Beispiel in C ++) nicht in Javascript kompiliert werden musste, sondern in etwas anderem. In etwas Neues, speziell als schnelle Alternative zu JS erstellt. Und so entstand WebAssembly.
Was ist in der ersten Version von WebAssembly enthalten? Was war genug, um den stolzen Titel „Minimum Viable Product“ zu erhalten?
Fähigkeit: Ziel-Compiler-Plattform

Die Programmierer, die an WebAssembly arbeiteten, verstanden, dass ihre Aufgabe nicht darin bestand, nur C oder C ++ zu unterstützen. Die Aufgabe bestand darin, die Möglichkeit zu geben, Code in einer beliebigen Sprache in WebAssembly zu kompilieren. Es musste sich um einen solchen „Assembler“ handeln, der im Browser ausgeführt werden sollte, so wie der Maschinencode der Desktop-Anwendung beispielsweise auf der x86-Plattform ausgeführt wird. Diese neue Sprache sollte sich jedoch nicht auf eine bestimmte Plattform stützen. Ihr Ziel sollte eine abstrakte Plattform auf einer höheren Ebene sein, deren spezifische Implementierung bereits von den auf dieser Hardware verwendeten Anweisungen abhängen würde.
Fähigkeit: schnelle Codeausführung

Alles musste schnell gehen. Warum sollte man sich sonst mit dieser ganzen Geschichte beschäftigen? Am Ende sollte der Benutzer in der Lage sein, wirklich "schwere" Anwendungen auszuführen, Top-Spiele im Browser zu spielen usw.
Fähigkeit: Kompaktheit

Es ist nicht nur wichtig, wie schnell der Code ausgeführt wird, sondern auch, wie schnell er geladen wird. Benutzer sind an Desktop-Anwendungen gewöhnt, die sehr schnell gestartet werden (da sie lokal installiert sind und über alle erforderlichen Ressourcen verfügen). Webanwendungen werden auch relativ schnell ausgeführt, da sie nicht so viele Ressourcen gleichzeitig laden. Dies stellt uns vor eine neue Herausforderung: Wenn wir eine neue Art von Webanwendung mit einer so großen Codebasis wie die klassische Desktop-Anwendung erstellen möchten, die jedoch aus dem Internet heruntergeladen werden kann, sollte der Code so kompakt wie möglich sein.
Fähigkeit: Speicherzugriff

Unsere neuen Anwendungen müssen auch etwas anders mit dem Speicher arbeiten als der JavaScript-Code. Benötigen Sie direkten Zugriff auf Speicherblöcke. Dies liegt an der Besonderheit der Sprachen C und C ++, in denen es Zeiger gibt. Ein Zeiger ist grob gesagt eine Variable, die eine Adresse im Speicher enthält. Eine Anwendung kann Daten an dieser Adresse lesen, ändern und sogar eine Arithmetik für einen Zeiger verwenden, um von der angegebenen Adresse im Speicher vorwärts zu „gehen“. Eine große Menge von C / C ++ - Code verwendet Zeiger, um die Effizienz seiner Arbeit zu steigern. Die Erstellung einer Zielplattform für solchen Code ist ohne die Unterstützung von Zeigern nicht möglich.
Wir können jedoch nicht zulassen, dass aus dem Internet heruntergeladener Code direkten Zugriff auf den Speicher unseres Prozesses hat - dies ist zu gefährlich. Wir müssen eine Umgebung erstellen, in der einerseits der in WebAssembly kompilierte native Code den direkten Speicherzugriff zulässt, andererseits den Bereich, in dem Daten bearbeitet werden dürfen, streng einschränkt.
Zu diesem Zweck verwendet WebAssembly das "lineare Speichermodell". Dies wird mithilfe von TypedArrays implementiert - so etwas wie ein Array in JavaScript, enthält jedoch nur einen sequentiellen Satz von Bytes im Speicher. Wenn Sie etwas einfügen möchten, verwenden Sie den Zugriff auf das Element über den Index (der eine Adresse im Speicher sein kann). Somit gibt dieses Array vor, ein Speicherblock für C ++ - Code zu sein.
Neue Leistung!
Mit all dem können die Benutzer die Desktop-Anwendung endlich in einem Browser mit ungefähr der gleichen Leistung ausführen, als wäre sie nativ. Das ist ungefähr dieser Funktionsumfang und wurde als "Minimum Viable Product" (MVP) bezeichnet.

Zu diesem Zeitpunkt könnten einige Anwendungen tatsächlich bereits unter WebAssembly erstellt werden und im Browser Geld verdienen. Aber es war noch ein langer Weg vor uns.
Schwergewichtige Desktop-Anwendungen

Der nächste wichtige Schritt sollte die Möglichkeit sein, wirklich große Desktop-Anwendungen zu starten. Können Sie sich vorstellen, dass die Vollversion von Photoshop in einem Browser ausgeführt wird? Und Sie haben es nicht installiert, sondern nur den Link geöffnet - und jetzt haben Sie die 100% ige Leistung dieses Produkts mit nativer Geschwindigkeit, der neuesten Version mit allen Updates und Korrekturen, auf jedem Gerät.
Und davon sind wir nicht weit entfernt - Beispiele tauchen bereits auf. Zum Beispiel AutoCAD. Und auch Adobe Lightroom. Aber seien wir ehrlich - in der aktuellen Implementierung von WebAssembly ist nicht alles bereit, um wirklich große Anwendungen zu starten. Engpässe werden genau hier untersucht und behoben, wenn Sie diesen Artikel lesen.
Fähigkeit: Multithreading

Natürlich brauchen wir Multithreading. Moderne Computer haben viele Kerne. Wir müssen sie nutzen können.
Fähigkeit: SIMD

Neben Multithreading gibt es eine weitere Technologie, die eine effizientere Implementierung der parallelen Datenverarbeitung ermöglicht. Dies ist SIMD: Verarbeitung mehrerer Datenblöcke gleichzeitig durch einen einzigen Befehl. Ein wichtiger Aspekt für eine wirklich schnelle WebAssembly.
Fähigkeit: 64-Bit-Adressierung

Ein weiteres wichtiges Merkmal der modernen Hardwarearchitektur, das in WebAssembly noch nicht verfügbar ist, ist die Unterstützung der 64-Bit-Speicheradressierung. Alles ist einfach: Mit 32-Bit-Adressen können Sie nur 4 GB Speicher verwenden (was für große Programme sehr klein ist), aber mit 64-Bit-Adressen sind es bereits bis zu 16 Exabyte (dies ist viel für moderne Software). Natürlich ist nicht nur das theoretische Maximum wichtig, sondern auch das praktische (wie viel Speicher das Betriebssystem Ihnen geben wird). Auf den meisten modernen Geräten sind jedoch bereits 4 oder mehr GB RAM vorhanden, und diese Anzahl wird zunehmen.
Fähigkeit: Stream-Zusammenstellung

Wir müssen nicht nur Anwendungen schnell ausführen. Wir müssen auch das Zeitintervall zwischen dem Start des Downloads über das Netzwerk und dem Start verkürzen. Mit der Stream-Kompilierung können Sie mit der Verarbeitung einer WebAssembly-Datei beginnen, bevor sie endgültig heruntergeladen wird. Wir überprüfen die Anweisungen beim Herunterladen über das Netzwerk. Das Laden und Kompilieren erfolgt also parallel. In Firefox-Code konnten wir eine Kompilierungsgeschwindigkeit erreichen, die
höher als die Download-Geschwindigkeit war. Das heißt, die Verarbeitungszeit eines Codes mit N Bytes war kürzer als die Download-Zeit dieses Codes über das Netzwerk. Entwickler anderer Browser arbeiten ebenfalls an der Stream-Kompilierung.

Eine Sache im Zusammenhang mit der Streaming-Kompilierung ist die Verwendung von
zwei Compilern . Eine davon (oben beschrieben) funktioniert schnell und ermöglicht es Ihnen, den heruntergeladenen Code sofort zu starten. Er führt jedoch nicht alle theoretisch möglichen Optimierungen durch, da dies mehr Zeit erfordert. Solche Optimierungen werden von einem anderen Compiler durchgeführt, der im Hintergrund arbeitet. Sobald er seine Arbeit beendet hat, ersetzt eine Version im Speicher eine andere und funktioniert stattdessen.
So erhalten wir sowohl den schnellen Start der Anwendung als auch deren effektiven Betrieb.
Fähigkeit: Caching

Wenn wir einmal WebAssembly-Code vom optimierenden Compiler heruntergeladen und kompiliert haben, ist es nicht sinnvoll, dasselbe zu tun, wenn Sie diesen Code auf eine andere Registerkarte laden (oder beim nächsten Öffnen des Browsers, sofern die Anwendung unverändert bleibt). Kompilierter Code kann (und sollte) zwischengespeichert und dann aus dem Cache verwendet werden.
Geschicklichkeit: andere Verbesserungen

Jetzt wird viel darüber diskutiert, welche anderen Verbesserungen möglich sind und worauf sich die Bemühungen der Entwickler konzentrieren sollten. Etwas wird definitiv realisiert, etwas nicht sofort, etwas wird überhaupt nicht passieren. Ich werde mit Ihrer Erlaubnis all diese Punkte in der allgemeinen Klasse „Sonstige Verbesserungen“ definieren, und was darin enthalten sein wird, werden wir mit der Zeit verstehen.
Wo sind wir jetzt
Irgendwo hier:

Multithreading
Für Multithreading haben wir einen fast fertigen
Plan , aber einer seiner
Hauptteile (
SharedArrayBuffers ) musste Anfang dieses Jahres
deaktiviert werden . Es wird bald wieder eingeschaltet und wir können fortfahren.
SIMD
Im Moment aktiv
entwickelt .
64-Bit-Adressierung
Für
wasm-64 haben wir eine ziemlich klare Vorstellung davon, wie die Dinge funktionieren sollten. Wir basierten auf x86- und ARM-Architekturansätzen.
Stream-Kompilierung
In Firefox wurde es bereits 2017
hinzugefügt , andere Browser arbeiten daran.
Verwenden von zwei Compilern
In Firefox wurde dies bereits 2017 und in anderen Browsern im Jahr 2018 hinzugefügt.
Implizites HTTP-Caching
In Firefox ist die Entwicklung
fast abgeschlossen , es wird bald eine Veröffentlichung geben.
Weitere Verbesserungen
Es gibt eine Diskussion
Wie Sie sehen können, befinden sich die meisten Elemente noch in der aktiven Entwicklung. Dennoch können wir bereits heute Anwendungen sehen, die auf WebAssembly ausgeführt werden, da die heutigen Funktionen bereits für jemanden ausreichen. Sobald alle oben genannten Funktionen verfügbar sind, werden wir eine weitere „neue Errungenschaft“ eröffnen und noch mehr neue Anwendungen werden WebAssembly-Unterstützung erhalten.

Javascript-Interaktion

WebAssembly wurde nicht nur als Plattform für Spiele und schwere Anwendungen entwickelt. Es kann für die regelmäßige Webentwicklung verwendet werden. Wir sind uns bewusst, dass heutzutage sehr große Webanwendungen in Javascript geschrieben sind und nur wenige beschließen, sie in WebAssembly zu übernehmen und vollständig neu zu schreiben. Der wichtige Punkt hierbei ist, dass dies nicht notwendig ist. Höchstwahrscheinlich funktionieren die meisten dieser Anwendungen recht gut und nur bei einigen Engpässen mangelt es möglicherweise an Leistung bei Berechnungen, Datenverarbeitungsbandbreite oder mangelnder Funktionalität, da eine JS-Version einer Bibliothek fehlt. Wir möchten Entwicklern die Möglichkeit geben, nur diese Engpässe in WebAssembly neu zu schreiben und den Rest des Codes in vertrauter JS zu belassen. Und das ist schon möglich. Durch das Umschreiben des Gutenberg-Parsers in Rust und das Erstellen unter WebAssebly gelang es uns beispielsweise, die Produktivität um das
86-fache zu steigern.
Aber um eine solche Übungsmasse und Bequemlichkeit zu schaffen, müssen wir etwas anderes implementieren.
Fähigkeit: schnelle Anrufe zwischen JS und WebAssembly

Das Aufrufen von WebAssembly von JS sollte sehr schnell funktionieren. Durch Hinzufügen eines kleinen WebAssembly-Moduls sollte der Programmierer keinen Leistungsverlust spüren, selbst wenn dieses Modul sehr oft aufgerufen wird. Dies ist bei MVP nicht der Fall (da das Ziel von MVP nicht darin bestand, die Leistung solcher Anrufe zu maximieren). Dieses Problem muss noch behoben werden. In Firefox haben wir bereits sichergestellt, dass einige JS-> WebAssembly-Aufrufe
bereits schneller sind als nicht inline JS-> JS-Aufrufe . Entwickler anderer Browser arbeiten ebenfalls an dieser Aufgabe.
Geschicklichkeit: schneller Datenaustausch

Diese Aufgabe ist mit der vorherigen verbunden: Es ist wichtig, nicht nur schnell WebAssembly-Code von JS aufzurufen, sondern auch schnell Daten zwischen diesen zu übertragen. Es gibt bestimmte Probleme damit. Zum Beispiel die Tatsache, dass WebAssembly nur Zahlen versteht. Es sind keine Objekte darin, aber in JS sind sie es. Es stellt sich heraus, dass wir eine Art Übersetzungsschicht brauchen. Es existiert bereits, ist aber immer noch nicht produktiv genug.
Fähigkeit: Integration mit ES-Modulen

Die Verwendung des WebAssembly-Moduls sieht jetzt so aus, als würde eine spezielle API aufgerufen, die das Modul zur Verwendung an Sie zurückgibt. Dies bedeutet jedoch, dass das WebAssembly-Modul nicht wirklich Teil des JS-Moduldiagramms der Webanwendung ist. Damit alle Funktionen für ES-Module verfügbar sind (z. B. Export und Import), muss das WebAssembly-Modul in ES-Module integriert werden können.
Fähigkeit: Integration in die Entwicklung

Nur importieren und exportieren zu können, bedeutet nicht, ein voll funktionsfähiges Modul zu werden. Wir brauchen einen Ort, an dem WebAssembly-Module verteilt werden können. Was ist das Analogon von npm für WebAssembly? Hmm ... wie wäre es mit npm selbst? Und was wird das Analogon von Webpack oder Parcel for WebAssembly sein? Hmm ... was ist mit Webpack und Paket?
WebAssembly-Module sollten sich nicht von normalen Modulen unterscheiden. Dies bedeutet, dass sie über dieselbe Infrastruktur verteilt werden können. Wir brauchen jedoch Tools, um sie in diese Infrastruktur zu integrieren.
Fähigkeit: Abwärtskompatibilität

Es gibt noch eine andere wichtige Sache, die wir bereitstellen müssen. Auch in älteren Browserversionen sollte alles gut funktionieren. Auch diejenigen, die keine Ahnung von WebAssembly haben. Wir müssen sicherstellen, dass der Entwickler nach dem Schreiben des Codes für WebAssembly nicht die zweite Version desselben Codes in Javascript schreiben muss, nur weil die Site auch in IE11 geöffnet werden muss.
Wo sind wir jetzt
Irgendwo hier:

Verknüpfungen zwischen JS und WebAssembly
In Firefox bereits
implementiert , wird in anderen Browsern gearbeitet.
Schneller Datenaustausch
Es gibt mehrere Vorschläge. Erweitern Sie beispielsweise das Typsystem in WebAssembly um Verweise auf JS-Objekte. Dies ist möglich, erfordert jedoch das Schreiben von zusätzlichem Code (z. B. zum Aufrufen von JS-Methoden), der nicht zu schnell funktioniert. Um dieses Problem zu lösen, gibt es wiederum mehrere Vorschläge.
Es gibt einen weiteren Aspekt im Zusammenhang mit dem Datenaustausch. Hier geht es darum zu verfolgen, wie lange Daten im Speicher gespeichert werden können. Wenn Sie Daten im Speicher haben, auf die der JS-Code Zugriff haben soll, müssen Sie diese dort belassen, bis der JS-Code sie liest. Aber wenn Sie sie für immer dort lassen, bekommen wir ein Speicherleck. Wie kann man herausfinden, dass Daten bereits gelöscht werden können (der JS-Code hat sie bereits gelesen)? Diese Verantwortung liegt heute beim Programmierer - alles wird manuell freigegeben. Sobald der JS-Code die Daten gelesen hat, sollte er so etwas wie die "freie" Funktion aufrufen. Dieser Ansatz ist jedoch veraltet und führt häufig zu Fehlern. Um dieses Problem zu lösen, haben wir das Konzept von
WeakRef in Javascript eingeführt. Dies ermöglicht es, Daten auf der Seite des JS-Codes zu lesen und, wenn der Garbage Collector funktioniert, den Speicher im WebAssembly-Modul korrekt zu löschen.
All dies befindet sich noch in der Entwicklung. In der Zwischenzeit
wurden im Rust-Ökosystem
Tools erstellt , die das Schreiben eines solchen Codes für Sie automatisieren und Teile, die noch nicht implementiert wurden, durch ihre eigene Implementierung ersetzen. Eines dieser Tools verdient besondere Erwähnung. Es heißt
wasm-bindgen . Wenn er bemerkt, dass Ihr Rust-Code versucht, JS-Objekte oder DOM-Objekte abzurufen oder zurückzugeben, erstellt er automatisch eine JS-Ebene, die mit Ihrem Rust-Code interagieren kann. Diese Ebene kann auch mit dem WebAssembly-Modul interagieren, das in einer anderen Sprache geschrieben ist, sodass nicht nur Rust-Programmierer dieses Tool verwenden können.
Integration mit ES-Modulen
Ein Arbeitsplan in diesem Bereich gibt es schon seit geraumer Zeit. Wir arbeiten gemeinsam mit Entwicklern anderer Browser aktiv daran.
Entwicklungsintegration
Es gibt bereits Tools wie
wasm-pack im Rust-Ökosystem, mit denen Sie automatisch alles, was Sie für die Veröffentlichung benötigen, in npm packen können. Und es gibt Leute, die dieses Tool verwenden, um ihre Module zu erstellen.
Abwärtskompatibilität
Aus Gründen der Abwärtskompatibilität haben wir das Tool wasm2js. Sie können eine WASM-Datei in eine entsprechende JS-Datei umwandeln. Dieser Javascript-Code ist nicht schnell, funktioniert jedoch in jedem Browser (einschließlich eines Browsers, der WebAssembly nicht unterstützt).
Wie Sie sehen, stehen wir diesem „Erfolg“ sehr nahe. Und sobald wir dies tun, wird sich der Weg zu zwei weiteren öffnen.

JS-Frameworks und JS-kompilierte Sprachen
Die erste ist die Möglichkeit, beliebte JS-Frameworks im Schwergewicht auf WebAssebly neu zu schreiben.

Die zweite Möglichkeit besteht darin, Programmiersprachen zu aktivieren, die in Javascript kompiliert werden, um sie durch WebAssembly zu ersetzen. Wir sprechen über Sprachen wie
Scala.js ,
Reason ,
Elm .

Für beide Aufgaben muss WebAssembly eine Reihe neuer Funktionen auf hoher Ebene unterstützen.
Fähigkeit: Müllsammler

Wir müssen aus mehreren Gründen in einen browserbasierten Garbage Collector integriert werden. Erinnern wir uns zunächst an die Aufgabe, JS-Frameworks (oder Teile davon) neu zu schreiben. Es kann erforderlich sein. , React DOM-, Rust . - . DOM , , . , , , . , .
JS-. - , . , , Javascript. JS- WebAssembly-, JS-.
( ), . , , . WebAssembly , .
Scala.js, Reason, Kotlin Elm — Javascript, . WebAssembly — WebAssembly ( ).
:

. , , Rust, . — . — . WebAssembly .
, Javascript. — - - . WebAssembly- JS-, — . Rust, , . , .
:

, JS-, . Javascript-. WebAssembly.
:

, "
". , — . , WebAssembly.
?
- :

Die Implementierung der Garbage Collection wird derzeit in zwei Richtungen durchgeführt: Dies sind
typisierte Objekte für JS und tatsächlich
der Garbage Collector für WebAssembly . Mit typisierten Objekten können Sie die klare Struktur des Objekts beschreiben. Es gibt bereits eine Vision, wie dies funktionieren soll, und sie wird auf dem bevorstehenden TC39-Treffen erörtert. Dementsprechend kann der GC für WebAssembly für seine eigenen Zwecke auf die obige Struktur zugreifen. An der Umsetzung wird bereits gearbeitet.
Sobald beide Teile fertig sind, erhalten wir durch die Interaktion von JS und WebAssembly ein System, das auf allen Ebenen verstehen kann, woraus das Objekt besteht, und dessen interne Daten effektiv nutzt. Wir haben bereits einen funktionierenden Prototyp. Der Prototyp kann jedoch nicht einfach übernommen und freigegeben werden - wir müssen einige Zeit für Standardisierung und Überarbeitungen aufwenden. Wir gehen davon aus, dass es irgendwann im Jahr 2019 veröffentlicht wird.
Ausnahmebehandlung
Die Arbeiten an
Ausnahmen werden derzeit erforscht und entwickelt. Wir prüfen verschiedene Vorschläge, versuchen sie umzusetzen und sehen, wie effektiv sie funktionieren.
Debuggen
Für das Debuggen gibt es bereits Unterstützung in den Firefox-Entwicklertools. Aber das Ideal ist noch weit weg. Wir möchten dem Entwickler seinen Quellcode und seine aktuelle Position darin zeigen und nicht nur Assembler-Anweisungen. Wir müssen Unterstützung für Symboldateien entwickeln und implementieren, die es uns ermöglichen, jede Codeanweisung mit der Quellzeile zu korrelieren.
Derzeit wird an der Spezifikation dieses Mechanismus gearbeitet.
Schwanz ruft
Es ist eine Arbeit in Arbeit .
Wenn alle oben genannten Schritte abgeschlossen sind, können wir davon ausgehen, dass wir den Erfolg „In JS kompilierte JS-Frameworks und -Sprachen“ erreicht haben.

Es war also ein Plan, um „Erfolge“ im Browser zu erzielen. Was passiert außerhalb des Browsers?
Aus dem Browser
Vielleicht war Ihnen die Kombination der Wörter "außerhalb des Browsers" peinlich. Haben wir wirklich etwas anderes als den Browser, wenn wir über das Web sprechen? Aber das "Web" haben wir direkt im Namen "WebAssembly". Tatsächlich sind HTML, CSS und JavaScript jedoch nur die Spitze des Eisbergs.

Ja, sie sind am besten sichtbar, weil sie die Benutzeroberfläche bilden. Aber es gibt noch einen anderen sehr wichtigen Teil des Webs - die Verbindungen. Die Verbindung von allem mit allem.

Ich kann jetzt auf Ihre Seite verlinken. Ich brauche weder Ihre noch die Erlaubnis eines anderen. Ich mache einfach diesen Link und füge ihn meiner Seite hinzu. Jeder kann ihm folgen und Ihr Inhalt wird angezeigt, der von Ihnen geschriebene Code wird gestartet. Diese Einfachheit, Verbindungen herzustellen und durch sie zu wechseln, hat unser Internet so geschaffen, wie es ist. Jetzt haben wir soziale Netzwerke und andere Websites, die das Konzept der „Verknüpfung“ im Wesentlichen um die Möglichkeit erweitern, alles anzudocken: Personen, Geräte, Unternehmen usw.
Bei all diesen Links und Links gibt es jedoch zwei Probleme.
Zu was sollte der Link führen? Wenn Sie irgendwohin gehen und die Site Ihnen Code bietet, der in Ihrem Browser ausgeführt werden muss, sollte dieser Code plattformübergreifend sein. Es sollte zu etwas kompiliert und auf einer Mohnblume, unter Windows, auf einem Android ausgeführt werden. Überall. Die Portabilität von herunterladbarem Code ist ein wichtiger Bestandteil des Konzepts der Webkonnektivität.

Es reicht jedoch nicht aus, nur den Code herunterzuladen und auszuführen. Sie müssen verstehen, dass wir nichts über diesen Code wissen. Wir vertrauen ihm nicht genug, um die volle Kontrolle über den Computer des Benutzers zu geben. Was ist, wenn es sich um bösartigen Code handelt? Er kann etwas Schlimmes tun. Und hier brauchen wir eine Art Sicherheitsmodell. Wir brauchen eine Sandbox, in der wir einen unbekannten Code einfügen, ihm kontrollierte Tools für die Arbeit geben können, aber alles, was wichtig und unsicher ist, entfernen können.

Das Konzept der „Kommunikation“ umfasst also zwei Aspekte: Portabilität und Sicherheit. Wir wissen, dass wir den Code definitiv ausführen können und dass er uns sicherlich nicht schaden wird. Warum bestehe ich auf diesen Konzepten und wie unterscheidet sich diese Sicht der Dinge von der Sicht des Webs als Kombination aus HTML, CSS und Javascript? Weil dieser Ansatz die Ansicht von WebAssembly grundlegend ändert.
Einerseits können wir uns WebAssembly als „ein weiteres Tool vorstellen, das in einem modernen Browser verfügbar ist“. Und so ist es auch.

Die Portabilität und Sicherheit der Codeausführung öffnen uns jedoch andere Türen.

Node.js

Wie kann WebAssembly Node helfen? Portabilität bringen.
Der Knoten bietet mithilfe von Javascript ein relativ hohes Maß an Portabilität. Es gibt jedoch immer noch viele Fälle, in denen die Leistung des JS-Codes nicht ausreicht oder nur der richtige JS-Code noch nicht geschrieben wurde, aber es gibt eine native Version davon. Und dann verwendet Node native Module. Sie sind in Sprachen wie C geschrieben und müssen für die spezifische Plattform kompiliert werden, auf der Ihr Knoten ausgeführt wird.
Native Module können entweder während der Installation kompiliert werden oder Sie können sie sofort für eine der gängigen Plattformen bereitstellen. Beide Ansätze sind möglich, aber dies ist nur eine Auswahl von zwei Übeln: entweder zusätzliche Kopfschmerzen für den Benutzer oder den Autor des Moduls.
Wenn Sie sich vorstellen, dass sich diese Module in WebAssembly befinden, müssen sie überhaupt nicht kompiliert werden. Mit Portability können Sie sie sofort auf jeder Plattform ausführen, z. B. mit Javascript-Code. Sie funktionieren jedoch mit der Leistung nativer Versionen.
Und hier kommt das Glück in die Welt von Node in Form der vollständigen Portabilität von allem und überall. Sie können die Node-Anwendung von Linux auf Windows portieren - und alles funktioniert ohne Neukompilierung weiter. Gleichzeitig hat das WebAssembly-Modul keinen Zugriff auf Systemressourcen (es funktioniert in seiner Sandbox). Aber native (und sogar nicht native) Node-Module funktionieren nicht in der Sandbox, sie haben Zugriff auf alles - das ist die Ideologie von Node. Damit das WebAssembly-Modul dieselben Funktionen erhält, ist eine zusätzliche Zugriffsebene auf Betriebssystemressourcen erforderlich. So etwas wie
POSIX- Funktionen (sie sind nicht notwendig, sie werden nur als Beispiel für eine relativ stabile und ausreichende Ressourcenzugriffsschnittstelle angegeben).
Fähigkeit: tragbare Schnittstelle

Was benötigen Node-Entwickler, um WebAssembly-Module zu verwenden? Eine Art Schnittstelle, um auf seine Funktionen zuzugreifen. Es wäre schön, es zu standardisieren. Nun, damit nicht nur Node diese Funktionen aufrufen kann, sondern auch jeder im Allgemeinen. Wenn Sie das WebAssembly-Modul in Ihrer Anwendung verwenden möchten, haben wir eine Verbindung hergestellt und verwenden es. So etwas wie "POSIX for WebAssembly". PWSIX (tragbare WebAssembly-Systemschnittstelle)?
Wo sind wir jetzt
Es gibt ein
Dokument , das den Mechanismus zum Bereitstellen eines Pfads zu einem Modul anhand seines Namens beschreibt. Dies wird wahrscheinlich sowohl von Browsern als auch von Node verwendet (sie können unterschiedliche Pfade bereitstellen). Es gibt zwar keine aktive Entwicklung, aber es wird viel diskutiert.

Höchstwahrscheinlich wird es in irgendeiner Form implementiert. Das ist gut, weil es uns eine Reihe von Möglichkeiten eröffnet.

CDN, Serverless und Edge Computing

Beispiele sind Dinge wie CDN, Serverless, Edge Computing. Fälle, in denen Sie Ihren Code auf den Server einer anderen Person stellen, wodurch die Verfügbarkeit für Clients sichergestellt wird. Warum benötigen Sie hier möglicherweise WebAssembly? Kürzlich gab es einen ausgezeichneten
Bericht zu diesem Thema. Kurz gesagt, es kann erforderlich sein, Code aus verschiedenen Quellen (die sich nicht gegenseitig vertrauen) innerhalb eines Prozesses auszuführen. Dieser Code muss voneinander und vom Betriebssystem isoliert sein. Lösungen wie eine virtuelle JS-Maschine (SpiderMonkey oder V8) funktionieren irgendwie, bieten jedoch nicht die gewünschte Leistung und Skalierbarkeit. Und WebAssembly - gibt.
Was ist erforderlich, damit dies funktioniert?
Fähigkeit: Laufzeit

Wir brauchen eine Laufzeitumgebung und einige Unternehmen erstellen ihre eigenen. Wir haben bereits WebAssembly-Compiler (wie
Cranelift ) - sie sind schnell und speichereffizient. Aber der von ihm generierte Code kann nicht in einem Vakuum leben - er muss sich auf etwas verlassen, irgendwie mit der Umgebung interagieren. Jetzt schreiben einige Unternehmen, wie z. B. Fastly, diese Laufzeitumgebung selbst. Dies ist jedoch kein sehr guter Ansatz - schließlich werden viele Unternehmen ihn benötigen und immer wieder die gleiche Arbeit leisten. Wir könnten es einmal tun, den Standard erweitern - und jedem eine Menge Ressourcen sparen.
Wo sind wir jetzt
Irgendwo hier:

Es gibt noch keinen Laufzeitstandard. Dies verhindert nicht, dass mehrere unabhängige Laufzeiten, die bereits in realen Projekten verwendet werden, existieren und funktionieren. Zum Beispiel
WAVM und wasmjit.
Wir planen auch die Veröffentlichung einer Laufzeit, die auf Cranelift basiert und als wasmtime bezeichnet wird. Und sobald wir etwas standardisiertes und funktionierendes haben, ist dies eine offene Gelegenheit, eine Reihe von Dingen zu entwickeln, wie zum Beispiel ...
Tragbare Befehlszeilenprogramme

WebAssembly kann nicht nur im Browser, sondern auch in herkömmlichen Betriebssystemen verwendet werden. Wir werden nicht über den Kernel sprechen (obwohl es auch
Draufgänger gibt, die dies winken), aber der WebAssembly-Code funktioniert möglicherweise im Benutzermodus. Auf diese Weise können Befehlszeilenprogramme erstellt werden, die nach ihrer Erstellung für jedes Betriebssystem garantiert gleich sind.
Internet der Dinge

Mit dem „Internet der Dinge“ sind normalerweise Geräte mit geringem Stromverbrauch gemeint (wie tragbare oder verschiedene Sensoren / Controller in „Smart Homes“). Einschränkungen der verfügbaren Prozessorressourcen und des Arbeitsspeichers wirken sich negativ auf die Fähigkeit aus, JS-Code dort auszuführen, aber WebAssembly ist eine ganz andere Sache. Die Optimierung von Compilern wie Cranelift und einer Laufzeit wie wasmtime wird unter solchen Bedingungen glänzen, da sie nur für ressourcenschonende Aufgaben geschrieben wurden. In absolut extremen Fällen ermöglicht WebAssembly sogar das Kompilieren Ihres Moduls in die native Binärdatei der Zielplattform. Nun, wieder Portabilität - es gibt heutzutage viele dieser IoT-Geräte, die auf verschiedenen Plattformen basieren. Mit WebAssembly müssen Sie sich darüber keine Gedanken machen - der entwickelte Code wird überall ausgeführt.
Schlussfolgerungen
Lassen Sie uns ein wenig zurückspulen und noch einmal einen Blick auf unseren „Fähigkeitsbaum“ werfen.

Ich habe diesen Artikel mit der Tatsache begonnen, dass einige Leute nicht verstehen, warum WebAssembly noch nicht fertig ist. Wie Sie jetzt verstehen können, hat sein Weg kaum begonnen. Ja, MVP eröffnet bereits einige Möglichkeiten. Wir können bereits etwas in WebAssembly kompilieren und in einem Browser ausführen. Aber es liegt noch viel Arbeit vor uns - Unterstützung für alles, was Sie für umfangreiche Anwendungen und Hochsprachen benötigen, Ersetzen von JS-Frameworks und all diese Dinge, über die ich außerhalb des Browsers gesprochen habe. Wenn dies alles fertig ist, werden wir ein neues Web sehen. Hohe Leistung, größer, tragbarer. Es wird keine solche Software mehr geben, die nicht für die Ausführung im Browser geschrieben werden kann: Spiele, Blockchain, Internet der Dinge, Befehlszeilenprogramme - alles wird gestartet.
WebAssembly ist nicht abgeschlossen. Er hat gerade erst begonnen.