Do not serialize remote objects unless needed

This patch stops serializing console API arguments unless there are
listeners of the 'console' event in puppeteer.

This saves quite a lot CPU cycles.

Fixes #117.
This commit is contained in:
Andrey Lushnikov 2017-07-24 21:43:54 -07:00
parent 236acec228
commit 5549ad0282
2 changed files with 22 additions and 4 deletions

View File

@ -232,6 +232,10 @@ class Page extends EventEmitter {
}
return;
}
if (!this.listenerCount(Page.Events.Console)) {
event.args.map(arg => helper.releaseObject(this._client, arg));
return;
}
let values = await Promise.all(event.args.map(arg => helper.serializeRemoteObject(this._client, arg)));
this.emit(Page.Events.Console, ...values);
}

View File

@ -45,7 +45,7 @@ class Helper {
/**
* @param {!Connection} client
* @param {!Object} remoteObject
* @return {!Object}
* @return {!Promise<!Object>}
*/
static async serializeRemoteObject(client, remoteObject) {
if (remoteObject.unserializableValue) {
@ -75,9 +75,23 @@ class Helper {
// Return description for unserializable object, e.g. 'window'.
return remoteObject.description;
} finally {
client.send('Runtime.releaseObject', {objectId: remoteObject.objectId}).catch(e => {
// While we were serializing object, the page might've navigated.
});
Helper.releaseObject(client, remoteObject);
}
}
/**
* @param {!Connection} client
* @param {!Object} remoteObject
* @return {!Promise}
*/
static async releaseObject(client, remoteObject) {
if (!remoteObject.objectId)
return;
try {
await client.send('Runtime.releaseObject', {objectId: remoteObject.objectId});
} catch (e) {
// Exceptions might happen in case of a page been navigated or closed.
// Swallow these since they are harmless and we don't leak anything in this case.
}
}