Skip to content

Instantly share code, notes, and snippets.

@chearon
Last active April 23, 2019 02:03
Show Gist options
  • Save chearon/57f03295853896be90a1f9e7d00b086c to your computer and use it in GitHub Desktop.
Save chearon/57f03295853896be90a1f9e7d00b086c to your computer and use it in GitHub Desktop.
Calculate average component render and patch times from a Chrome profile
// 1. Set Vue.config.performance = true
// 2. Record a profile while doing something
// 3. Save the profile to your disk
// 4. curl -s https://gist.githubusercontent.com/chearon/57f03295853896be90a1f9e7d00b086c/raw/vue-component-perf-stats.js | node - -- filename
const {createReadStream} = require('fs');
const readline = require('readline');
const input = createReadStream(process.argv[process.argv.length - 1]);
const rl = readline.createInterface({input});
const events = [];
let lineNumber = 0;
let loggedError = false;
function padLeft(input, size) {
return Array(size - input.length + 1).join(" ") + input;
}
rl.on('line', line => {
if (line.indexOf('vue <') > -1) {
const s = line === 0 ? 1 : 0;
const e = line.length - 1;
let event;
try {
event = JSON.parse(line.slice(s, e));
} catch (e) {
if (!loggedError) console.error(`Error parsing line ${lineNumber}`);
loggedError = true;
}
if (event && event.name.startsWith('vue <')) {
events.push(event);
}
}
lineNumber += 1;
});
rl.on('close', () => {
console.log(`collected ${events.length} events from ${lineNumber} total`);
const averages = new Map();
let skipped = 0;
for (let i = 0; i < events.length; i += 2) {
const e1 = events[i];
const e2 = events[i + 1];
if (e1.id !== e2.id || e1.ph !== 'b' || e2.ph !== 'e' || e1.name !== e2.name) {
skipped += 1;
continue;
}
const time = e2.ts - e1.ts;
if (!averages.has(e1.name)) {
averages.set(e1.name, {count: 1, avg: time});
} else {
const entry = averages.get(e1.name);
entry.count += 1;
entry.avg += (time - entry.avg) / entry.count;
}
}
if (skipped > 0) console.error(`skipped ${skipped} mismatched events, did devtools change?`);
let maxNameLength = 0;
let maxCountLength = 0;
for (const name of averages.keys()) maxNameLength = Math.max(maxNameLength, name.length);
for (const {count} of averages.values()) maxCountLength = Math.max(maxCountLength, String(count).length);
for (const [name, entry] of averages.entries()) {
console.log(`${padLeft(name, maxNameLength + 1)} (${padLeft('x' + entry.count, maxCountLength + 1)}): ${entry.avg * 10e-4}ms`);
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment