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

LDNWebPerf December 2016 - Ingvar Stepanyan

LDNWebPerf December 2016 - Ingvar Stepanyan

Avatar for London Web Performance Group

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; });