Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor Chrome trace to get renderblocking #1995

Merged
merged 1 commit into from
Sep 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 6 additions & 41 deletions lib/chrome/webdriver/chromium.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,7 @@ import { parse } from '../traceCategoriesParser.js';
import { pathToFolder } from '../../support/pathToFolder.js';
import { ChromeDevtoolsProtocol } from '../chromeDevtoolsProtocol.js';
import { Android, isAndroidConfigured } from '../../android/index.js';
import {
getFirstContentFulPaintEvent,
getLargestContentfulPaintEvent,
getRecalculateStyleElementsAndTimeBefore
} from './traceUtilities.js';
import { getRenderBlocking } from './traceUtilities.js';
const unlink = promisify(_unlink);
const rm = promisify(_rm);

Expand Down Expand Up @@ -356,50 +352,19 @@ export class Chromium {
result.cpu = cpu;

// Collect render blocking info
const renderBlockingInfo = {};
const urlsWithBlockingInfo = trace.traceEvents.filter(
task =>
task.cat === 'devtools.timeline' &&
task.name === 'ResourceSendRequest' &&
task.args.data.url &&
task.args.data.renderBlocking
);
for (let asset of urlsWithBlockingInfo) {
renderBlockingInfo[asset.args.data.url] =
asset.args.data.renderBlocking;
}

const fcpEvent = getFirstContentFulPaintEvent(trace.traceEvents);
const lcpEvent = getLargestContentfulPaintEvent(trace.traceEvents);

result.renderBlocking = { recalculateStyle: {}, requests: {} };

if (fcpEvent) {
const beforeFCP = getRecalculateStyleElementsAndTimeBefore(
trace.traceEvents,
fcpEvent.ts
);
result.renderBlocking.recalculateStyle.beforeFCP = beforeFCP;
}

if (lcpEvent) {
const beforeLCP = getRecalculateStyleElementsAndTimeBefore(
trace.traceEvents,
lcpEvent.ts
);
result.renderBlocking.recalculateStyle.beforeLCP = beforeLCP;
}
const render = await getRenderBlocking(trace);
result.renderBlocking = render.renderBlocking;

if (!this.options.skipHar) {
for (let harRequest of this.hars[index - 1].log.entries) {
if (renderBlockingInfo[harRequest.request.url]) {
if (render.renderBlockingInfo[harRequest.request.url]) {
harRequest._renderBlocking =
renderBlockingInfo[harRequest.request.url];
render.renderBlockingInfo[harRequest.request.url];
}
}
}

result.renderBlocking.requests = renderBlockingInfo;
result.renderBlocking.requests = render.renderBlockingInfo;
}

// Google Web Vitals hacksery
Expand Down
47 changes: 41 additions & 6 deletions lib/chrome/webdriver/traceUtilities.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import intel from 'intel';
const log = intel.getLogger('browsertime.chrome');

export function getLargestContentfulPaintEvent(traceEvents) {
function getLargestContentfulPaintEvent(traceEvents) {
const lcpCandidates = traceEvents.filter(
task => task.name === 'largestContentfulPaint::Candidate'
);
Expand All @@ -20,7 +20,7 @@ export function getLargestContentfulPaintEvent(traceEvents) {
}
}

export function getFirstContentFulPaintEvent(traceEvents) {
function getFirstContentFulPaintEvent(traceEvents) {
// Get first contentful paint
const fcpEvent = traceEvents.find(
task => task.name === 'firstContentfulPaint'
Expand All @@ -33,10 +33,7 @@ export function getFirstContentFulPaintEvent(traceEvents) {
}
}

export function getRecalculateStyleElementsAndTimeBefore(
traceEvents,
timestamp
) {
function getRecalculateStyleElementsAndTimeBefore(traceEvents, timestamp) {
const recalculatesBefore = traceEvents.filter(
task =>
task.cat === 'disabled-by-default-devtools.timeline' &&
Expand All @@ -62,3 +59,41 @@ export function getRecalculateStyleElementsAndTimeBefore(

return { elements, durationInMillis: duration / 1000 };
}

export async function getRenderBlocking(trace) {
const renderBlockingInfo = {};

const urlsWithBlockingInfo = trace.traceEvents.filter(
task =>
task.cat === 'devtools.timeline' &&
task.name === 'ResourceSendRequest' &&
task.args.data.url &&
task.args.data.renderBlocking
);
for (let asset of urlsWithBlockingInfo) {
renderBlockingInfo[asset.args.data.url] = asset.args.data.renderBlocking;
}

const fcpEvent = getFirstContentFulPaintEvent(trace.traceEvents);
const lcpEvent = getLargestContentfulPaintEvent(trace.traceEvents);

const renderBlocking = { recalculateStyle: {}, requests: {} };

if (fcpEvent) {
const beforeFCP = getRecalculateStyleElementsAndTimeBefore(
trace.traceEvents,
fcpEvent.ts
);
renderBlocking.recalculateStyle.beforeFCP = beforeFCP;
}

if (lcpEvent) {
const beforeLCP = getRecalculateStyleElementsAndTimeBefore(
trace.traceEvents,
lcpEvent.ts
);
renderBlocking.recalculateStyle.beforeLCP = beforeLCP;
}

return { renderBlockingInfo, renderBlocking };
}
46 changes: 5 additions & 41 deletions lib/core/engine/command/chromeTrace.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
import intel from 'intel';

import {
getFirstContentFulPaintEvent,
getLargestContentfulPaintEvent,
getRecalculateStyleElementsAndTimeBefore
} from '../../../chrome/webdriver/traceUtilities.js';
import { getRenderBlocking } from '../../../chrome/webdriver/traceUtilities.js';
import { parse } from '../../../chrome/traceCategoriesParser.js';
import { parseCPUTrace } from '../../../chrome/parseCpuTrace.js';
const log = intel.getLogger('browsertime.command.chrometrace');
Expand Down Expand Up @@ -47,50 +43,18 @@ export class ChromeTrace {
result.cpu = cpu;

// Collect render blocking info
const renderBlockingInfo = {};
const urlsWithBlockingInfo = trace.traceEvents.filter(
task =>
task.cat === 'devtools.timeline' &&
task.name === 'ResourceSendRequest' &&
task.args.data.url &&
task.args.data.renderBlocking
);
for (let asset of urlsWithBlockingInfo) {
renderBlockingInfo[asset.args.data.url] =
asset.args.data.renderBlocking;
}

const fcpEvent = getFirstContentFulPaintEvent(trace.traceEvents);
const lcpEvent = getLargestContentfulPaintEvent(trace.traceEvents);

result.renderBlocking = { recalculateStyle: {}, requests: {} };
const render = await getRenderBlocking(trace);

if (fcpEvent) {
const beforeFCP = getRecalculateStyleElementsAndTimeBefore(
trace.traceEvents,
fcpEvent.ts
);
result.renderBlocking.recalculateStyle.beforeFCP = beforeFCP;
}

if (lcpEvent) {
const beforeLCP = getRecalculateStyleElementsAndTimeBefore(
trace.traceEvents,
lcpEvent.ts
);
result.renderBlocking.recalculateStyle.beforeLCP = beforeLCP;
}
result.renderBlocking = render.renderBlocking;

if (!this.options.skipHar) {
for (let harRequest of this.hars[this.index - 1].log.entries) {
if (renderBlockingInfo[harRequest.request.url]) {
if (render.renderBlockingInfo[harRequest.request.url]) {
harRequest._renderBlocking =
renderBlockingInfo[harRequest.request.url];
render.renderBlockingInfo[harRequest.request.url];
}
}
}

result.renderBlocking.requests = renderBlockingInfo;
}
} else {
throw new Error('Trace only works in Chrome');
Expand Down