Web Workers handling AJAX calls - optimisation overkill?

JavaScript performance comparison

Revision 7 of this test case created by

Preparation code

<script>!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.immediate=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){

'use strict';
var types = [
  _dereq_('./nextTick'),
  _dereq_('./mutation.js'),
  _dereq_('./messageChannel'),
  _dereq_('./stateChange'),
  _dereq_('./timeout')
];
var draining;
var queue = [];
//named nextTick for less confusing stack traces
function nextTick() {
  draining = true;
  var i, oldQueue;
  var len = queue.length;
  while (len) {
    oldQueue = queue;
    queue = [];
    i = -1;
    while (++i < len) {
      oldQueue[i]();
    }
    len = queue.length;
  }
  draining = false;
}
var scheduleDrain;
var i = -1;
var len = types.length;
while (++ i < len) {
  if (types[i] && types[i].test && types[i].test()) {
    scheduleDrain = types[i].install(nextTick);
    break;
  }
}
module.exports = immediate;
function immediate(task) {
  if (queue.push(task) === 1 && !draining) {
    scheduleDrain();
  }
}
},{"./messageChannel":2,"./mutation.js":3,"./nextTick":6,"./stateChange":4,"./timeout":5}],2:[function(_dereq_,module,exports){
(function (global){

'use strict';

exports.test = function () {
  if (global.setImmediate) {
    // we can only get here in IE10
    // which doesn't handel postMessage well
    return false;
  }
  return typeof global.MessageChannel !== 'undefined';
};

exports.install = function (func) {
  var channel = new global.MessageChannel();
  channel.port1.onmessage = func;
  return function () {
    channel.port2.postMessage(0);
  };
};
}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{}],3:[function(_dereq_,module,exports){
(function (global){

'use strict';
//based off rsvp https://github.com/tildeio/rsvp.js
//license https://github.com/tildeio/rsvp.js/blob/master/LICENSE
//https://github.com/tildeio/rsvp.js/blob/master/lib/rsvp/asap.js

var Mutation = global.MutationObserver || global.WebKitMutationObserver;

exports.test = function () {
  return Mutation;
};

exports.install = function (handle) {
  var called = 0;
  var observer = new Mutation(handle);
  var element = global.document.createTextNode('');
  observer.observe(element, {
    characterData: true
  });
  return function () {
    element.data = (called = ++called % 2);
  };
};
}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{}],4:[function(_dereq_,module,exports){
(function (global){

'use strict';

exports.test = function () {
  return 'document' in global && 'onreadystatechange' in global.document.createElement('script');
};

exports.install = function (handle) {
  return function () {

    // Create a <script> element; its readystatechange event will be fired asynchronously once it is inserted
    // into the document. Do so, thus queuing up the task. Remember to clean up once it's been called.
    var scriptEl = global.document.createElement('script');
    scriptEl.onreadystatechange = function () {
      handle();

      scriptEl.onreadystatechange = null;
      scriptEl.parentNode.removeChild(scriptEl);
      scriptEl = null;
    };
    global.document.documentElement.appendChild(scriptEl);

    return handle;
  };
};
}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{}],5:[function(_dereq_,module,exports){

'use strict';
exports.test = function () {
  return true;
};

exports.install = function (t) {
  return function () {
    setTimeout(t, 0);
  };
};
},{}],6:[function(_dereq_,module,exports){

},{}]},{},[1])
(1)
});</script>
      
<script>
Benchmark.prototype.setup = function() {
  function getData() {
    var jsonString = '{"coord":{"lon":-0.13,"lat":51.51},"sys":{"type":1,"id":5091,"message":0.8232,"country":"GB","sunrise":1412575813,"sunset":1412616405},"weather":[{"id":520,"main":"Rain","description":"light intensity shower rain","icon":"09d"},{"id":310,"main":"Drizzle","description":"light intensity drizzle rain","icon":"09d"}],"base":"cmc stations","main":{"temp":284.96,"pressure":1001,"humidity":81,"temp_min":283.15,"temp_max":286.35},"wind":{"speed":5.1,"deg":170,"var_beg":140,"var_end":210,"gust":11.3},"clouds":{"all":75},"dt":1412602600,"id":2643743,"name":"London","cod":200}';
  
    var ajaxCall = new XMLHttpRequest();
    return JSON.parse(jsonString);
  }
  
  var URL = window.URL || window.webkitURL || window.mozURL || window.msURL || window.oURL;
  
  var code = getData.toString() + 'onmessage = function(e) {postMessage(getData());};';
  var bb = new Blob([code], {
    type: 'text/javascript'
  });
  var bbURL = URL.createObjectURL(bb);
  window._worker = new Worker(bbURL);

};

Benchmark.prototype.teardown = function() {
  window._worker.terminate();
  URL.revokeObjectURL(bbURL);

};
</script>

Test runner

Warning! For accurate results, please disable Firebug before running the tests. (Why?)

Java applet disabled.

Testing in CCBot 2.0.0 / Other 0.0.0
Test Ops/sec
Without WebWorkers sync
getData();
pending…
With WebWorkers
// async test
window._worker.onmessage = function() {
  deferred.resolve();
};
window._worker.postMessage(""); //worker will run `getData` and return the result
pending…
Without WebWorkers async
// async test
getData();
immediate(function() {
  deferred.resolve();
});
pending…

Compare results of other browsers

Revisions

You can edit these tests or add even more tests to this page by appending /edit to the URL.

0 Comments