UNPKG

browsertime

Version:

Get performance metrics from your web page using Browsertime.

127 lines (113 loc) 3.39 kB
import { getLogger } from '@sitespeed.io/log'; import { computeMainThreadTasks, computeScriptCosts, computeForcedReflows, computeNonCompositedAnimations } from './trace/index.js'; const log = getLogger('browsertime.chrome.cpu'); function round(number_, decimals = 3) { const pow = Math.pow(10, decimals); return Math.round(number_ * pow) / pow; } function slowestFirst(a, b) { return b.value - a.value; } export async function parseCPUTrace(tracelog, url) { try { log.debug('Start parse Chrome trace log using Tracium.'); const tasks = computeMainThreadTasks(tracelog, { flatten: true }); log.debug('Finished parsing the trace log using Tracium.'); const categories = { parseHTML: 0, styleLayout: 0, paintCompositeRender: 0, scriptParseCompile: 0, scriptEvaluation: 0, garbageCollection: 0, other: 0 }; const events = {}; const urls = {}; for (const task of tasks) { categories[task.kind] += task.selfTime; if (events[task.event.name]) { events[task.event.name] += task.selfTime; } else { events[task.event.name] = task.selfTime; } if (task.attributableURLs && task.attributableURLs.length > 0) { for (let url of task.attributableURLs) { if (urls[url]) { urls[url] += task.selfTime; } else { urls[url] = task.selfTime; } } } } // Fix decimals for (let category of Object.keys(categories)) { categories[category] = round(categories[category], 0); } // Only report events with more than 10 ms const eventLimit = 10; for (let event of Object.keys(events)) { if (events[event] > eventLimit) { events[event] = round(events[event]); } else { delete events[event]; } } // Only report URLs with more than 10 ms const limit = 10; const cleanedUrls = []; for (let url of Object.keys(urls)) { if (urls[url] > limit) { cleanedUrls.push({ url, value: round(urls[url]) }); } } cleanedUrls.sort(slowestFirst); // New analyses derived from the same trace. Each is independent // of the others and won't produce noise on pages where the // signal isn't present (empty arrays). Wrapped in a try so a // bug in one analysis can't poison the existing categories / // events / urls payload. let scriptCosts = []; let forcedReflows = []; let nonCompositedAnimations = []; try { scriptCosts = computeScriptCosts(tracelog); } catch (error) { log.debug('computeScriptCosts failed: %s', error.message); } try { forcedReflows = computeForcedReflows(tracelog); } catch (error) { log.debug('computeForcedReflows failed: %s', error.message); } try { nonCompositedAnimations = computeNonCompositedAnimations(tracelog); } catch (error) { log.debug('computeNonCompositedAnimations failed: %s', error.message); } log.debug('Chrome trace log finished parsed and sorted.'); return { categories, events, urls: cleanedUrls, scriptCosts, forcedReflows, nonCompositedAnimations }; } catch (error) { log.error( 'Could not parse the trace log from Chrome for url %s', url, error ); return {}; } }