Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

I need more info about Puppeteer page.metrics and queryObjects

I'm using Puppeteer to find a memory leak issue. I'm using puppeteer's page.metrics() API but I am having trouble understanding each properties meaning. All my values in the metrics keep increasing in value over time. Is this expected? Or is this an indication that there might be a serious memory leak?

The properties which are growing in value as the app runs are: JSEventListeners, Nodes, LayoutCount, RecalcStyleCount, LayoutDuration, RecalcStyleDuration, ScriptDuration, TaskDuration, JSHeapUsedSize, JSHeapTotalSize

The information about this stuff is very sparse and also I keep seeing people refer to page.queryObjects as another way to find memory leaks. But I cannot find any information about how to use this API and what to look for.

like image 487
Evan Larsen Avatar asked Feb 05 '18 19:02

Evan Larsen


1 Answers

According to the Puppeteer Documentation:

page.metrics()

  • returns: <Promise<Object>> Object containing metrics as key/value pairs.
    • Timestamp <number> The timestamp when the metrics sample was taken.
    • Documents <number> Number of documents in the page.
    • Frames <number> Number of frames in the page.
    • JSEventListeners <number> Number of events in the page.
    • Nodes <number> Number of DOM nodes in the page.
    • LayoutCount <number> Total number of full or partial page layout.
    • RecalcStyleCount <number> Total number of page style recalculations.
    • LayoutDuration <number> Combined durations of all page layouts.
    • RecalcStyleDuration <number> Combined duration of all page style recalculations.
    • ScriptDuration <number> Combined duration of JavaScript execution.
    • TaskDuration <number> Combined duration of all tasks performed by the browser.
    • JSHeapUsedSize <number> Used JavaScript heap size.
    • JSHeapTotalSize <number> Total JavaScript heap size.

NOTE All timestamps are in monotonic time: monotonically increasing time in seconds since an arbitrary point in the past.

page.queryObjects(prototypeHandle)

  • prototypeHandle <JSHandle> A handle to the object prototype.
  • returns: <Promise<JSHandle>> Promise which resolves to a handle to an array of objects with this prototype.

The method iterates the JavaScript heap and finds all the objects with the given prototype.

// Create a Map object
await page.evaluate(() => window.map = new Map());
// Get a handle to the Map object prototype
const mapPrototype = await page.evaluateHandle(() => Map.prototype);
// Query all map instances into an array
const mapInstances = await page.queryObjects(mapPrototype);
// Count amount of map objects in heap
const count = await page.evaluate(maps => maps.length, mapInstances);
await mapInstances.dispose();
await mapPrototype.dispose();

Shortcut for page.mainFrame().executionContext().queryObjects(prototypeHandle).


The page.metrics() method returns the result of the Chrome DevTools Protocol Performance.getMetrics:

Performance.getMetrics

Retrieve current values of run-time metrics.

RETURN OBJECT

  • metrics array Metric
    • Current values for run-time metrics.

On the other hand, the Chrome DevTools Protocol that accompanies the page.queryObjects() method is Runtime.queryObjects:

Runtime.queryObjects

PARAMETERS

  • prototypeObjectId RemoteObjectId
    • Identifier of the prototype to return objects for.
  • objectGroup string (optional)
    • Symbolic group name that can be used to release the results.

RETURN OBJECT

  • objects RemoteObject
    • Array with objects.

The source code for page.matrics() and page.queryObjects() can be found on GitHub.

like image 53
Grant Miller Avatar answered Oct 12 '22 22:10

Grant Miller