Loading time is a major factor in page abandonment and loyalty; 53% of users
report that they abandon sites that take more than three seconds to
load (source: SOASTA Google study report).
Users visit more often, stay longer, search more, and buy more frequently on
sites that load quickly than on slower ones; one company found that a
conversion increase of 7% resulted from a speed improvement of as
little as .85 seconds (source: WPO Stats).
Slow loading is detrimental for search engine optimization
(SEO) because it can lower your site's ranking, resulting in fewer
visits, reads, and conversions; in 2018, Google will implement site speed as a
ranking signal in its mobile searches (source: Search Engine Land).
---
# Le langage imposé
---
background-image: url(./img/firefox.png)
background-size: 50% auto
# [@bnjbvr](https://twitter.com/bnjbvr)
.left[such [floss](https://framasoft.org)]
.right[very [mozilla](https://mozilla.org)]
.left[so [kresus](https://kresus.org)]
.bigger.right[wow]
???
Je suis ingénieur logiciel, travaille pour mozilla, je raconte ma vie,
blablabla on n'est pas là pour écouter ma biographie.
---
class: white-bg
background-image: url(./img/logo.png)
---
class: bigger
# C'est quoi WebAssembly ?
### Un **environnement d'exécution** rapide, stable, bien défini, aux performances proches du natif.
--
### Un nouveau **standard** créé en coopération par Apple, Google, Microsoft et Mozilla.
--
### Un format **binaire** compact, portable, rapide à charger et à *compiler*.
--
### Tout ça intégré dans la plateforme Web.
???
Draft W3C depuis le 15 fevrier 2018
WG/CG (réunion tous les mois / deux semaines)
Intégré = plus de plugins (cause de crashes), facile à distribuer (pas d'app
store), à mettre à jour, etc.
---
class: middle, center, white-bg
# Support des navigateurs
--
![Dans tous les navigateurs](./img/browsers.png)
???
A l'heure de l'écriture, représente 71% des navigateurs selon CanIUse.
Attention support dans Safari pour iOS, activé puis désactivé puis réactivé.
Existence d'un polyfill dans un sous ensemble de JS (asm.js) => amélioration
progressive.
---
# C'est efficace ?
--
## plus rapide à démarrer
## plus rapide à s'exécuter
## plus compact
--
## debuggable
???
Démarrage : fichier binaire, pas de parsing, pas d'exécution lazy, tiered
compilation, streaming compilation, mise en cache.
Exécution : langage statique typé, correspondance directe avec le CPU, pas
d'allocation mémoire (GC), précompilation par un gros compilateur. On est
seulement à un petit écart de 20% des performances natives, et ça n'arrête pas
d'évoluer !
Compact : binaire, moins à télécharger, moins de représentations internes en
mémoire, moins à stocker en mémoire, économie en bande-passante donc coûts
serveurs.
Debugable : format binaire, mais représentation textuelle pour pouvoir
inspecter le code source et le deboguer ! et source maps !
---
# Cas d'utilisation
## Porter des [programmes complets](https://www.youtube.com/watch?v=TwuIRcpeUWE)
--
## Porter des [libs](https://websightjs.com/index-video.html)
--
## Utilisation dans des [libs](https://www.youtube.com/watch?v=qfnkDyHVJzs&feature=youtu.be&t=5880)
--
## Utilisation dans des [apps web](http://www.adultswim.com/etcetera/elastic-man)
???
Programmes complets : Unity / Unreal Engine.
Porter des libs : OpenCV, NaCL (crypto), compression, codecs, etc.
Utilisation dans des libs : React pour Fiber, Glimmer VM pour Ember, etc.
Utilisation dans des apps web : c'est ce qui nous intéresse ici !
---
class: middle
# Pourquoi dans votre app Web ?
--
### Résoudre une problématique spécifique de performances
--
### ... Changer de langage ?
???
Premature optimization root of all evil.
- Trouver les 20% de code qui prennent 80% du temps, avec un profiler.
- Optimiser ces 20%.
- S'il y a un autre problème de performance, reprendre un profiler.
---
class: bigger
# Ces langages qui compilent vers wasm
- C/C++ ([Emscripten](http://emscripten.org/), LLVM)
- .NET ([Blazor](https://github.com/aspnet/blazor))
- JVM ([TeaVM](https://github.com/konsoletyper/teavm))
- Go
- Elixir
- Kotlin
- Faust
--
- [... et tous les autres](https://github.com/appcypher/awesome-wasm-langs)
--
- Rust !
---
class: middle, center
# Rust
![Rust loves JS](./img/rust_love_js.png)
(Copyright [Lin Clark](https://hacks.mozilla.org/2018/03/making-webassembly-better-for-rust-for-all-languages))
???
- Langage bas-niveau / "système"
- Mais avec une expressivité haut niveau
- Très rapide (langage compilé, typé statiquement)
- Vous empêche de faire des erreurs au moment de la compilation
- Multithreadé et safe
Initiative de Mozilla, mais utilisation dépasse Moz.
Dropbox, CoreOS, Coursera, OVH, npm inc, ... et GlimmerVM dans Ember !
---
# C++ 🔫 👣
```c++
struct Obj {
int x;
Obj(int x) : x(x) {}
};
void func(Obj** obj) {
Obj tmp(42);
*obj = &tmp;
}
void main() {
Obj* obj;
func(&obj);
std::cout << obj->x << std::endl;
}
```
---
# Rust 😅
```rust
fn main() {
let x: &i32;
{
let y = 100;
x = &y;
}
println!("Hello, {}", *x);
}
```
---
# Sauvé par le compilateur !
```
error[E0597]: `y` does not live long enough
--> src/main.rs:5:14
|
5 | x = &y;
| ^ borrowed value does not live long enough
6 | }
| - `y` dropped here while still borrowed
7 | println!("Hello, {}", *x);
8 | }
| - borrowed value needs to live until here
error: aborting due to previous error
For more information about this error, try
`rustc --explain E0597`.
```
---
# Installer Rust
### A ne faire qu'une seule fois ⚠️
```
curl https://sh.rustup.rs -sSf | sh
export PATH=$HOME/.cargo/bin:$PATH
rustup toolchain install nightly
rustup target add wasm32-unknown-unknown --toolchain nightly
```
???
Attention en téléchargeant et streamant dans sh.
---
# Commencer un projet
Initialiser le projet :
```
cargo +nightly new --lib example
```
Ajouter dans le fichier `Cargo.toml` :
```
[lib]
crate-type = ["cdylib"]
```
Build vers WebAssembly :
```
cd example
cargo +nightly build --target wasm32-unknown-unknown \
--release
```
---
### [Rust](./example/index.html)
```rust
#[no_mangle]
pub extern fn add_one(a: u32) -> u32 {
a + 1
}
```
--
### JavaScript
```js
// ⚠️ mimetype application/wasm
const response = fetch('example.wasm');
(async function() {
let { instance } =
await WebAssembly.instantiateStreaming(response);
let result = instance.exports.add_one(41);
alert(`The answer is ${result}`);
})();
```
---
# Problèmes de cette approche
### Etape de *build* pas intégrée
### Nécessité de toucher aux APIs WebAssembly
### Interactions plus complexes ?
### Interopérabilité avec des types plus complexes ?
???
Wasm fournit beaucoup d'abstractions bas niveau (table de fonctions, fonctions,
bloc de mémoire linéaire), mais ne permet pas d'utiliser des types plus haut
niveau : chaîne de caractères, booléens, ou types définis par les devs.
Possibilité d'appeler des fonctions JS depuis Wasm et inversement.
---
class: bigger
# [Passer une chaîne de caractères](./example/complex.html)
### De JS à Rust
- transformer cette chaîne dans sa représentation en octets
- mettre cette représentation en mémoire wasm
- côté Rust, construire une chaîne depuis cette représentation
--
### De Rust à JS
- la même... en sens inverse !
---
class: center, middle
# Et si des outils faisaient le travail pour nous ?
---
# Build / bundle
Webpack >= 4.0.0 / Parcel >= v1.5.0
```
npm install -g webpack@4.0.1
```
Et ensuite :
```
import * as wasm from './module.wasm';
```
---
# wasm-bindgen
Pour l'interopérabilité entre les deux mondes.
```
cargo install wasm-bindgen-cli
```
Ajouter au `Cargo.toml` :
```
[dependencies]
wasm-bindgen = "0.2"
```
Des annotations dans le code...
Après le build Rust :
```
wasm-bindgen \
target/wasm32-unknown-unknown/release/project_name.wasm \
--out-dir .
```
???
wasm-bindgen génère du code Rust et du code JS pour interagir plus facilement
entre les deux mondes.
- le code wasm résultant contient un tout petit allocateur de mémoire pour
pouvoir passer des paramètres (via la mémoire wasm).
- et des wrappers Rust pour reconstruire les arguments passés depuis la mémoire
ou les valeurs retournées vers la mémoire par les fonctions.
- le code JS contient des wrappers pour simplifier le passage de valeurs dans
l'autre sens également.
Au final :
- 1 fichier JS qui propose une interface similaire à celle du code Rust
- 1 fichier wasm qui sera importé par le module JS
Outil générique, destiné à fonctionner avec tous les langages sources.
Mais comment les outils (compilateur et wasm-bindgen) savent quel code
augmenter ?
---
# Annotations wasm-bindgen
```rust
#![feature(proc_macro, wasm_custom_section, \
wasm_import_module)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
extern {
// Declare a JavaScript function.
fn alert(msg: &str);
}
```
---
# Déclarer une fonction
```rust
#[wasm_bindgen]
pub extern fn hello_world(name: &str) {
let formatted = format!("Hello, {}", name);
alert(&formatted);
}
```
```js
import('./project.js').then(project => {
project.hello_world("Benjamin");
});
```
---
# Déclarer un type
```rust
#[wasm_bindgen]
pub struct HelloFactory {
name: String
}
#[wasm_bindgen]
impl HelloFactory {
pub fn new(name: String) -> HelloFactory {
HelloFactory { name: name }
}
pub fn say_hello(&self) {
alert(&format!("Hello, {}", self.name));
}
}
```
```js
import('./project.js').then(project => {
let factory = project.HelloFactory.new("Benjamin");
factory.say_hello();
factory.free();
});
```
---
class: middle, center, bigger
# Démo complète : un correcteur de typos
Benjamin, j'espère que t'as pas oublié de lancer `webpack-dev-server`, sinon
[ce lien](http://localhost:8080) ne va pas marcher.
???
Quid des autres langages ?
---
# Et le futur ?
--
### host bindings
--
### garbage collector
--
### shared array buffers
--
Et tout le reste : SIMD, exception handling,...
---
class: center, middle
# En résumé
### plus rapide à charger
### plus rapide à l'exécution
--
### *B.Y.O.L* (Bring Your Own Langage)
---
class: middle, center
# Merci !
### slides : [bnjbvr.github.io/slides/2018/wasm-mixit](https://bnjbvr.github.io/slides/2018/wasm-mixit)
### canal IRC : [#wasm](https://kiwiirc.com/client/irc.mozilla.org/#wasm) sur irc.mozilla.org
### Rust+Wasm : [github.com/rustwasm](https://github.com/rustwasm/)
### WebAssembly : [webassembly.org](https://webassembly.org/)
### Infos : [@WasmWeekly](https://twitter.com/WasmWeekly)
### [@bnjbvr](https://twitter.com/bnjbvr)