use static function instead of closure

pull/2/head
gorhill 10 years ago
parent 8db990daa3
commit e0eaf97eb4

@ -704,26 +704,18 @@ vAPI.messaging.onMessage = function({target, data}) {
.chromeEventHandler.ownerDocument.defaultView.messageManager;
}
var listenerId = data.channelName.split('|');
var requestId = data.requestId;
var channelName = listenerId[1];
listenerId = listenerId[0];
var channelNameRaw = data.channelName;
var pos = channelNameRaw.indexOf('|');
var channelName = channelNameRaw.slice(pos + 1);
var callback = vAPI.messaging.NOOPFUNC;
if ( requestId !== undefined ) {
callback = function(response) {
var message = JSON.stringify({
requestId: requestId,
channelName: channelName,
msg: response !== undefined ? response : null
});
if ( messageManager.sendAsyncMessage ) {
messageManager.sendAsyncMessage(listenerId, message);
} else {
messageManager.broadcastAsyncMessage(listenerId, message);
}
};
if ( data.requestId !== undefined ) {
callback = CallbackWrapper.factory(
messageManager,
channelName,
channelNameRaw.slice(0, pos),
data.requestId
).callback;
}
var sender = {
@ -798,6 +790,67 @@ vAPI.messaging.broadcast = function(message) {
/******************************************************************************/
// This allows to avoid creating a closure for every single message which
// expects an answer. Having a closure created each time a message is processed
// has been always bothering me. Another benefit of the implementation here
// is to reuse the callback proxy object, so less memory churning.
//
// https://developers.google.com/speed/articles/optimizing-javascript
// "Creating a closure is significantly slower then creating an inner
// function without a closure, and much slower than reusing a static
// function"
//
// http://hacksoflife.blogspot.ca/2015/01/the-four-horsemen-of-performance.html
// "the dreaded 'uniformly slow code' case where every function takes 1%
// of CPU and you have to make one hundred separate performance optimizations
// to improve performance at all"
var CallbackWrapper = function(messageManager, channelName, listenerId, requestId) {
this.callback = this.proxy.bind(this); // bind once
this.init(messageManager, channelName, listenerId, requestId);
};
CallbackWrapper.junkyard = [];
CallbackWrapper.factory = function(messageManager, channelName, listenerId, requestId) {
var wrapper = CallbackWrapper.junkyard.pop();
if ( wrapper ) {
wrapper.init(messageManager, channelName, listenerId, requestId);
return wrapper;
}
return new CallbackWrapper(messageManager, channelName, listenerId, requestId);
};
CallbackWrapper.prototype.init = function(messageManager, channelName, listenerId, requestId) {
this.messageManager = messageManager;
this.channelName = channelName;
this.listenerId = listenerId;
this.requestId = requestId;
};
CallbackWrapper.prototype.proxy = function(response) {
var message = JSON.stringify({
requestId: this.requestId,
channelName: this.channelName,
msg: response !== undefined ? response : null
});
if ( this.messageManager.sendAsyncMessage ) {
this.messageManager.sendAsyncMessage(this.listenerId, message);
} else {
this.messageManager.broadcastAsyncMessage(this.listenerId, message);
}
// Mark for reuse
this.messageManager =
this.channelName =
this.requestId =
this.listenerId = null;
CallbackWrapper.junkyard.push(this);
};
/******************************************************************************/
var httpObserver = {
classDescription: 'net-channel-event-sinks for ' + location.host,
classID: Components.ID('{dc8d6319-5f6e-4438-999e-53722db99e84}'),

Loading…
Cancel
Save