UNPKG

browsertime

Version:

Get performance metrics from your web page using Browsertime.

109 lines (92 loc) 3.49 kB
import path from 'node:path'; import intel from 'intel'; import { pathToFolder } from '../support/pathToFolder.js'; import { BrowserError } from '../support/errors.js'; import { isAndroidConfigured, Android } from '../android/index.js'; const delay = ms => new Promise(res => setTimeout(res, ms)); const log = intel.getLogger('browsertime.firefox'); /** * Timeout a promise after ms. Use promise.race to compete * about the timeout and the promise. * @param {promise} promise - The promise to wait for * @param {int} ms - how long in ms to wait for the promise to fininsh * @param {string} errorMessage - the error message in the Error if we timeouts */ async function timeout(promise, ms, errorMessage) { let timer; return Promise.race([ new Promise((resolve, reject) => { timer = setTimeout(reject, ms, new BrowserError(errorMessage)); return timer; }), promise.then(value => { clearTimeout(timer); return value; }) ]); } export class MemoryReport { constructor(runner, storageManager, firefoxConfig, options) { this.runner = runner; this.storageManager = storageManager; this.firefoxConfig = firefoxConfig; this.options = options; } /** * The memory report parser will measure the total resident memory of the * entire firefox browser. It does this by summing up the "resident" memory * of the parent process together with the "resident-unique" memory for each * subprocess. */ async parse(reportFilename, subDir) { const report = JSON.parse( await this.storageManager.readData(reportFilename, subDir) ); let memory = 0; for (const entry of Object.values(report.reports)) { if (entry.process.startsWith('Main Process')) { if (entry.path === 'resident') { memory += entry.amount; } } else { if (entry.path === 'resident-unique') { memory += entry.amount; } } } return memory; } async collect(index, url) { const runner = this.runner; const firefoxConfig = this.firefoxConfig; const options = this.options; let subDir = pathToFolder(url, options); let profileDir = await this.storageManager.createSubDataDir(subDir); let reportFilename = `memory-report-${index}.json.gz`; let destinationFilename = path.join(profileDir, reportFilename); let deviceReportFilename = destinationFilename; if (isAndroidConfigured(options)) { deviceReportFilename = `/sdcard/Android/data/${firefoxConfig.android.package}/files/memoryReport-${index}.json`; } let minimizeFirst = 'false'; if (firefoxConfig.memoryReportParams.minizeFirst) { minimizeFirst = 'true'; } log.info( `Collecting memory report from ${deviceReportFilename} to ${destinationFilename}` ); let script = `Cc['@mozilla.org/memory-info-dumper;1'].getService(Ci.nsIMemoryInfoDumper).dumpMemoryReportsToNamedFile(String.raw\`${deviceReportFilename}\`, null, null, false, ${minimizeFirst});`; await timeout( runner.runPrivilegedScript(script, 'Collecting memory report'), 1_200_000, 'Could not get memory report' ); // Add a delay in case the memory report is still writing to disk. await delay(3000); if (isAndroidConfigured(options)) { const android = new Android(options); await android._downloadFile(deviceReportFilename, destinationFilename); } return this.parse(reportFilename, subDir); } }