diff --git a/CHANGELOG.md b/CHANGELOG.md index ea538fd..5b752bb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,8 @@ # CHANGELOG - Chrome-trace ## UNRELEASED +### Added +* Include time per category up until the 'firstPaint' mark in the output. ### Fixed * Improve categorization of events to more closely match Chrome DevTools. diff --git a/lib/eventProcessors/durationEvents/durationProcessor.js b/lib/eventProcessors/durationEvents/durationProcessor.js index c55ddb9..854d516 100644 --- a/lib/eventProcessors/durationEvents/durationProcessor.js +++ b/lib/eventProcessors/durationEvents/durationProcessor.js @@ -51,9 +51,10 @@ function roundAndFilter(timePerType) { }, {}); } -module.exports = function createProcessor(name, keyFromEvent) { +module.exports = function createProcessor(name, keyFromEvent, endMark) { const eventSyntesizer = createEventSyntesizer(); const eventsPerThread = {}; + let cutoffTime = undefined; return { processEvent(event) { @@ -62,6 +63,13 @@ module.exports = function createProcessor(name, keyFromEvent) { } switch (event.ph) { + case 'R': + { + if (endMark === event.name) { + cutoffTime = event.ts; + } + } + break; case 'B': return eventSyntesizer.processBeginEvent(event); case 'E': @@ -76,17 +84,25 @@ module.exports = function createProcessor(name, keyFromEvent) { } } }, - getResult: function() { + getResult() { const timePerThread = {}; for (const [threadId, events] of Object.entries(eventsPerThread)) { - const sortedEvents = events.sort((a, b) => a.ts - b.ts); + let sortedEvents = events.sort((a, b) => a.ts - b.ts); + if (cutoffTime !== undefined) { + sortedEvents = sortedEvents.filter(e => e.ts < cutoffTime).map(e => { + if (e.ts + e.dur > cutoffTime) { + e.dur = cutoffTime - e.ts; + } + return e; + }); + } let eventStack = []; const timePerType = sortedEvents.reduce((result, event) => { - result[keyFromEvent(event)] = - (result[keyFromEvent(event)] || 0) + event.dur; + const key = keyFromEvent(event); + result[key] = (result[key] || 0) + event.dur; eventStack = findParentEvents(eventStack, event); diff --git a/lib/eventProcessors/eventCategoryTime.js b/lib/eventProcessors/eventCategoryTime.js index 1251eda..619c518 100644 --- a/lib/eventProcessors/eventCategoryTime.js +++ b/lib/eventProcessors/eventCategoryTime.js @@ -16,6 +16,10 @@ const eventCategory = event => { return category; }; -module.exports = function createProcessor() { - return durationProcessor('eventCategoryTime', eventCategory); +module.exports = function createProcessor(cutoffMark) { + let key = 'eventCategoryTime'; + if (cutoffMark) { + key += `|${cutoffMark}`; + } + return durationProcessor(key, eventCategory, cutoffMark); }; diff --git a/lib/eventProcessors/index.js b/lib/eventProcessors/index.js index e58e894..37cc8fd 100644 --- a/lib/eventProcessors/index.js +++ b/lib/eventProcessors/index.js @@ -6,12 +6,13 @@ const cpuEventsPerThread = require('./eventTypeTime'); const cpuCategoriesPerThread = require('./eventCategoryTime'); module.exports = { - createProcessors(options = {}) { + createProcessors() { return [ - mainThread(options), - threadName(options), - cpuEventsPerThread(options), - cpuCategoriesPerThread(options) + mainThread(), + threadName(), + cpuEventsPerThread(), + cpuCategoriesPerThread(), + cpuCategoriesPerThread('firstPaint') ]; } }; diff --git a/test/tests.js b/test/tests.js index dd2fcef..c24d4cc 100644 --- a/test/tests.js +++ b/test/tests.js @@ -105,6 +105,24 @@ test('Can categorize events per category in www.google.ru file', async t => { ); }); +test.failing('Can filter events before firstPaint', async t => { + const parsed = await parseTracelog('www.google.ru.json'); + const categories = parsed['eventCategoryTime|firstPaint'][parsed.mainThread]; + // Within 5% of what Chrome DevTools reports + t.true( + roughlyEquals( + categories, + { + Loading: 9.2, + Painting: 0.3, + Rendering: 27.1, + Scripting: 40.8 + }, + 5 + ) + ); +}); + test.todo('Counts time for nested events'); test.todo('Handles X events out of order');