Upgrade to Pro — share decks privately, control downloads, hide ads and more …

LDNWebPerf December 2016 - Ingvar Stepanyan

LDNWebPerf December 2016 - Ingvar Stepanyan

London Web Performance Group

December 06, 2016
Tweet

More Decks by London Web Performance Group

Other Decks in Technology

Transcript

  1. Abusing ES6+ features for nicer parallelism * Disclaimer: no people,

    animals or JS features were harmed during the talk Ingvar Stepanyan aka @RReverser
  2. Calculation in the main thread // get inputs var x

    = document.getElementById("x").value; var y = document.getElementById("y").value; // VERY useful calculations for (var end = Date.now() + 3000; Date.now() < end; ); var result = x * y; // output result document.getElementById("output").value = result; jsbin
  3. Web Workers: client (main thread) var worker = new Worker("worker.js");

    worker.addEventListener("message", function (event) { // output result document.getElementById("output").value = event.data.result; }); // get inputs var x = document.getElementById("x").value; var y = document.getElementById("y").value; worker.postMessage({ x: x, y: y });
  4. Web Workers: server (worker) self.addEventListener("message", function (event) { // get

    inputs var x = event.data.x; var y = event.data.y; // VERY useful calculations for (var end = Date.now() + 3000; Date.now() < end; ); var result = x * y; postMessage({ result: result }); });
  5. Web Workers: client (main thread) var worker = new Worker("worker.js"),

    inc = 0; // get inputs var id = inc++; var x = document.getElementById("x").value; var y = document.getElementById("y").value; worker.addEventListener("message", function handler(event) { if (event.data.id === id) { this.removeEventListener("message", handler); // output result document.getElementById("output").value = event.data.result; } }); worker.postMessage({ id: id, x: x, y: y });
  6. Web Workers: server (worker) self.addEventListener("message", function (event) { // get

    inputs var id = event.data.id; var x = event.data.x; var y = event.data.y; // VERY useful calculations for (var end = Date.now() + 3000; Date.now() < end; ); var result = x * y; postMessage({ id: id, result: result }); }); jsbin
  7. Calculation in the main thread // get inputs var x

    = document.getElementById("x").value; var y = document.getElementById("y").value; // VERY useful calculations for (var end = Date.now() + 3000; Date.now() < end; ); var result = x * y; // output result document.getElementById("output").value = result;
  8. Web Workers //// index.js ////
 var worker = new Worker("worker.js"),

    inc = 0; // get inputs var id = inc++; var x = document.getElementById("x").value; var y = document.getElementById("y").value; worker.addEventListener("message", function handler(event) { if (event.data.id === id) { this.removeEventListener("message", handler); // output result document.getElementById("output").value = event.data.result; } }); worker.postMessage({ id: id, x: x, y: y }); //// worker.js ////
 self.addEventListener("message", function (event) { // get inputs var id = event.data.id; var x = event.data.x; var y = event.data.y; // VERY useful calculations for (var end = Date.now() + 3000; Date.now() < end;); var result = x * y; postMessage({ id: id, result: result }); });
  9. Calculation in the main thread // get inputs var x

    = document.getElementById("x").value; var y = document.getElementById("y").value; // VERY useful calculations for (var end = Date.now() + 3000; Date.now() < end; ); var result = x * y; // output result document.getElementById("output").value = result;
  10. Dream API parallel(function () { // get inputs var x

    = document.getElementById("x").value; var y = document.getElementById("y").value; // VERY useful calculations for (var end = Date.now() + 3000; Date.now() < end;); var result = x * y; // output result document.getElementById("output").value = result; });
  11. ES6: Promise API doSomethingAsync().then( function onSuccess(result) {}, function onError(error) {}

    ) // or just: return doSomethingAsync().then(function (result) { // do something with result })
  12. ES6: Promise API $.ajax(url).then(function (data) { $('#result').html(data); var status =

    $('#status').html('Download complete.'); return status.fadeIn().promise().then(function () { return sleep(2000); }).then(function () { return status.fadeOut(); }); });
  13. ES6: Promise API $.ajax(url).then(data => { $('#result').html(data); var status =

    $('#status').html('Download complete.'); return ( status.fadeIn().promise() .then(() => sleep(2000)) .then(() => status.fadeOut()) ); });
  14. ES8: async/await var data = await $.ajax(url); $('#result').html(data); var status

    = $('#status').html('Download complete.'); await status.fadeIn.promise(); await sleep(2000); await status.fadeOut();
  15. ES8: async/await var expr = await promise;
 nextStatement(); var expr;

    promise.then(result => { expr = result; nextStatement(); });
  16. ES6: Proxy API var proxy = new Proxy({}, { get(target,

    name) { return name; }, set(target, name, value) { console.log(name, '=', value); }, // ... }); proxy.a; // 'a' proxy[0]; // '0' proxy.a = 1; // console: 'a = 1' proxy.b = 2; // console: 'b = 2'
  17. ES6: Proxy API var proxy = new Proxy({}, { get(target,

    name) { if (name === 'then') { return resolve => resolve(target.name); } return new Proxy({ name }, this); } }); proxy.a.then(console.log); // 'a' proxy.a.b.c.then(console.log); // 'c' proxy[0].then(console.log); // '0'
  18. Let’s mix! var proxy = new Proxy({}, { get(target, name)

    { if (name === 'then') { return resolve => resolve(target.name); } return new Proxy({ name }, this); } }); console.log(await proxy.a); // ‘a' console.log(await proxy.a.b.c); // 'c' console.log(await proxy[0]); // '0'
  19. Let’s mix! var proxy = new Proxy({}, { get(target, name)

    { var chain = { type: 'get', target, name }; if (name === 'then') { return askMainThread(chain); } return new Proxy(chain, this); } }); proxy.a; // {type: 'get', target: {}, name: 'a'} proxy.a.b; // {type: 'get', target: {…, name: 'a'}, name: 'b'} await proxy.a.b.c; // 'a.b.c'
  20. ES6: Proxy API await proxy.document.getElementById('x').value // into: askMainThread({ type: 'get',

    target: { type: 'call', target: { type: 'get', target: { type: 'get', target: {}, name: 'document' }, name: 'getElementById' }, args: ['x'] }, name: 'value' })(resolve => …, reject => …)
  21. ES8-powered API parallel(async function (proxy) { // get inputs var

    x = await proxy.document.getElementById("x").value; var y = await proxy.document.getElementById("y").value; // VERY useful calculations for (var end = Date.now() + 3000; Date.now() < end;); var result = x * y; // output result proxy.document.getElementById("output").value = result; });
  22. ES8-powered API (just like we wanted!) parallel(async function ({ document

    }) { // get inputs var x = await document.getElementById("x").value; var y = await document.getElementById("y").value; // VERY useful calculations for (var end = Date.now() + 3000; Date.now() < end;); var result = x * y; // output result document.getElementById("output").value = result; });