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.
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
metricsarray 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
prototypeObjectIdRemoteObjectId
- Identifier of the prototype to return objects for.
objectGroupstring (optional)
- Symbolic group name that can be used to release the results.
RETURN OBJECT
objectsRemoteObject
- Array with objects.
The source code for page.matrics() and page.queryObjects() can be found on GitHub.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With