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

new_audit: add cumulative layout shift metric #9037

Merged
merged 42 commits into from
Feb 28, 2020
Merged
Show file tree
Hide file tree
Changes from 30 commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
0fe7bbb
new_audit: add layout stability metric
paulirish Feb 25, 2019
c4b153d
hacks for making it look cool
paulirish Mar 19, 2019
eab48c8
Merge branch 'master' into layoutstability
paulirish May 23, 2019
a825fc4
fixups
paulirish May 23, 2019
9c7c148
todo
paulirish May 23, 2019
14a6228
hide from report
paulirish May 23, 2019
8897105
lint
paulirish May 23, 2019
8e5eceb
Merge branch 'master' into layoutstability
paulirish Sep 12, 2019
8ccafa1
sample json
paulirish Sep 12, 2019
54adb9f
debug stuff
paulirish Sep 13, 2019
8c4bbf1
Merge branch 'master' into layoutstability
paulirish Nov 6, 2019
09cb0f0
hide from report
paulirish Nov 6, 2019
2f71438
rename to Cumulative Layout Shift
paulirish Nov 6, 2019
396ad39
rename files
paulirish Nov 6, 2019
54bf68c
revert report change
paulirish Nov 6, 2019
eac986c
lint
paulirish Nov 6, 2019
17ec87a
snapshots
paulirish Nov 7, 2019
6b9a996
move off of ComputedMetric class
paulirish Nov 7, 2019
1374765
last renames
paulirish Nov 7, 2019
aaab275
dont need devtoolsLogs
paulirish Nov 7, 2019
79b2c4f
Merge remote-tracking branch 'origin/master' into layoutstability
connorjclark Nov 10, 2019
66687e9
Apply suggestions from code review
connorjclark Nov 10, 2019
25f56f6
pr changes
connorjclark Nov 10, 2019
f234753
Merge remote-tracking branch 'origin/master' into layoutstability
connorjclark Nov 10, 2019
12f4197
fix tests
connorjclark Nov 10, 2019
4b4387c
update
connorjclark Nov 10, 2019
c35ed5a
comment about proto. rename layout shift error
connorjclark Nov 11, 2019
efb69e6
comment
connorjclark Nov 11, 2019
d09fbb3
report found trace event signal as debugdata
paulirish Dec 18, 2019
9542b6c
python3 i love you SO MUCH. >:|
paulirish Dec 18, 2019
b525650
snapshots
paulirish Dec 31, 2019
8be4c07
snapshots
paulirish Dec 31, 2019
d625e4c
snapshots
paulirish Jan 6, 2020
8e8782f
shane's wording
paulirish Jan 27, 2020
30f77ac
json
paulirish Jan 27, 2020
7b7ae5e
Merge branch 'master' into layoutstability
paulirish Feb 5, 2020
2dad8a8
numericUnit === 'shiftarinos'. also considering: gigashifts, megamove…
paulirish Feb 5, 2020
1e52204
unitless
paulirish Feb 11, 2020
61de864
tweak scoring
paulirish Feb 19, 2020
7b0865d
samplejson
paulirish Feb 24, 2020
811f170
Merge branch 'master' into layoutstability
paulirish Feb 28, 2020
d9ea769
resolve merge conflict
paulirish Feb 28, 2020
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
81 changes: 81 additions & 0 deletions lighthouse-core/audits/metrics/cumulative-layout-shift.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/**
* @license Copyright 2019 Google Inc. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
*/
'use strict';

const Audit = require('../audit.js');
const ComputedCLS = require('../../computed/metrics/cumulative-layout-shift.js');
const i18n = require('../../lib/i18n/i18n.js');

const UIStrings = {
/** The name of the metric "Cumulative Layout Shift" that indicates how much the page changes its layout while it loads. If big segments of the page shift their location during load, the Cumulative Layout Shift will be higher. Shown to users as the label for the numeric metric value. Ideally fits within a ~40 character limit. */
title: 'Cumulative Layout Shift',
// TODO(paulirish): improve this description.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

poke

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'Perfectly solid == 0. Unpleasant experience >= 0.50.',

we dont have any additional data right now in order to be more concrete than this.

the TODO is to be addressed before shipping 6.0

/** Description of the Cumulative Layout Shift metric that indicates how much the page changes its layout while it loads. If big segments of the page shift their location during load, the Cumulative Layout Shift will be higher. This description is displayed within a tooltip when the user hovers on the metric name to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */
description: 'The more the page\'s layout changes during its load, the higher the ' +
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The pattern we use is " ." So I took a stab at it.

"Cumulative Layout Shift is the sum of all layout shifts that occurred during a page's load. A layout shift is any movement an element makes once it is visible to the user. All layout shift is recorded, scored, and then aggregated into a cumulative score between 0 and 1; 0 being a perfectly stable page, and >=0.5 being a highly shifting page."

'Cumulative Layout Shift. ' +
'Perfectly solid == 0. Unpleasant experience >= 0.50.',
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it feels like this should be scaled somehow... is it possible for there to ever be some human interpretable understanding of this? like a scale such that CLS Index: 5284 means that the total weighted shift of your layout objects was 5284% of the page size or something

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe we need to leave a TODO in here for improving this description, too? :)

};

const str_ = i18n.createMessageInstanceIdFn(__filename, UIStrings);

/**
* @fileoverview This metric represents the amount of visual shifting of DOM elements during page load.
*/
class CumulativeLayoutShift extends Audit {
/**
* @return {LH.Audit.Meta}
*/
static get meta() {
return {
id: 'cumulative-layout-shift',
title: str_(UIStrings.title),
description: str_(UIStrings.description),
scoreDisplayMode: Audit.SCORING_MODES.NUMERIC,
requiredArtifacts: ['traces'],
};
}

/**
* @return {LH.Audit.ScoreOptions}
*/
static get defaultOptions() {
return {
// TODO(paulirish): Calibrate these
scorePODR: 0.1,
scoreMedian: 0.5,
};
}

/**
* @param {LH.Artifacts} artifacts
* @param {LH.Audit.Context} context
* @return {Promise<LH.Audit.Product>}
*/
static async audit(artifacts, context) {
const trace = artifacts.traces[Audit.DEFAULT_PASS];
const metricResult = await ComputedCLS.request(trace, context);

/** @type {LH.Audit.Details.DebugData} */
const details = {
type: 'debugdata',
items: [metricResult.debugInfo],
};

return {
score: Audit.computeLogNormalScore(
metricResult.value,
context.options.scorePODR,
context.options.scoreMedian
),
numericValue: metricResult.value,
displayValue: metricResult.value.toLocaleString(context.settings.locale),
details,
};
}
}

module.exports = CumulativeLayoutShift;
module.exports.UIStrings = UIStrings;
61 changes: 61 additions & 0 deletions lighthouse-core/computed/metrics/cumulative-layout-shift.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/**
* @license Copyright 2019 Google Inc. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
*/
'use strict';

const makeComputedArtifact = require('../computed-artifact.js');
const TraceOfTab = require('../trace-of-tab.js');
const LHError = require('../../lib/lh-error.js');

class CumulativeLayoutShift {
/**
* @param {LH.Trace} trace
* @param {LH.Audit.Context} context
* @return {Promise<{value: number, debugInfo: Record<string,boolean> | null}>}
*/
static async compute_(trace, context) {
const traceOfTab = await TraceOfTab.request(trace, context);

// Find the last LayoutShift event, if any.
let finalLayoutShift;
for (let i = traceOfTab.mainThreadEvents.length - 1; i >= 0; i--) {
const evt = traceOfTab.mainThreadEvents[i];
if (evt.name === 'LayoutShift' && evt.args && evt.args.data && evt.args.data.is_main_frame) {
finalLayoutShift = evt;
break;
}
}

const finalLayoutShiftTraceEventFound = !!finalLayoutShift;
// tdresser sez: In about 10% of cases, layout instability is 0, and there will be no trace events.
// TODO: Validate that. http://crbug.com/1003459
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This bug was fixed, is this still valid?

Suggested change
// TODO: Validate that. http://crbug.com/1003459
// TODO(http://crbug.com/1003459): Validate that.

if (!finalLayoutShift) {
return {
value: 0,
debugInfo: {
finalLayoutShiftTraceEventFound,
},
};
}

const cumulativeLayoutShift =
finalLayoutShift.args &&
finalLayoutShift.args.data &&
finalLayoutShift.args.data.cumulative_score;

if (cumulativeLayoutShift === undefined) {
throw new LHError(LHError.errors.LAYOUT_SHIFT_MISSING_DATA);
}

return {
value: cumulativeLayoutShift,
debugInfo: {
finalLayoutShiftTraceEventFound,
},
};
}
}

module.exports = makeComputedArtifact(CumulativeLayoutShift);
6 changes: 6 additions & 0 deletions lighthouse-core/computed/metrics/timing-summary.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const FirstMeaningfulPaint = require('./first-meaningful-paint.js');
const LargestContentfulPaint = require('./largest-contentful-paint.js');
const FirstCPUIdle = require('./first-cpu-idle.js');
const Interactive = require('./interactive.js');
const CumulativeLayoutShift = require('./cumulative-layout-shift.js');
const SpeedIndex = require('./speed-index.js');
const EstimatedInputLatency = require('./estimated-input-latency.js');
const MaxPotentialFID = require('./max-potential-fid.js');
Expand Down Expand Up @@ -45,6 +46,7 @@ class TimingSummary {
const largestContentfulPaint = await requestOrUndefined(LargestContentfulPaint, metricComputationData); // eslint-disable-line max-len
const firstCPUIdle = await requestOrUndefined(FirstCPUIdle, metricComputationData);
const interactive = await requestOrUndefined(Interactive, metricComputationData);
const cumulativeLayoutShift = await requestOrUndefined(CumulativeLayoutShift, trace);
const maxPotentialFID = await requestOrUndefined(MaxPotentialFID, metricComputationData);
const speedIndex = await requestOrUndefined(SpeedIndex, metricComputationData);
const estimatedInputLatency = await EstimatedInputLatency.request(metricComputationData, context); // eslint-disable-line max-len
Expand All @@ -69,6 +71,8 @@ class TimingSummary {
estimatedInputLatencyTs: estimatedInputLatency.timestamp,
totalBlockingTime: totalBlockingTime.timing,
maxPotentialFID: maxPotentialFID && maxPotentialFID.timing,
cumulativeLayoutShift: cumulativeLayoutShift && cumulativeLayoutShift.value !== null ?
cumulativeLayoutShift.value : undefined,

// Include all timestamps of interest from trace of tab
observedNavigationStart: traceOfTab.timings.navigationStart,
Expand All @@ -87,6 +91,8 @@ class TimingSummary {
observedLoadTs: traceOfTab.timestamps.load,
observedDomContentLoaded: traceOfTab.timings.domContentLoaded,
observedDomContentLoadedTs: traceOfTab.timestamps.domContentLoaded,
observedCumulativeLayoutShift: traceOfTab.timings.cumulativeLayoutShift,
observedCumulativeLayoutShiftTs: traceOfTab.timestamps.cumulativeLayoutShift,

// Include some visual metrics from speedline
observedFirstVisualChange: speedline.first,
Expand Down
2 changes: 2 additions & 0 deletions lighthouse-core/config/default-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ const defaultConfig = {
'metrics/estimated-input-latency',
'metrics/total-blocking-time',
'metrics/max-potential-fid',
'metrics/cumulative-layout-shift',
'errors-in-console',
'time-to-first-byte',
'metrics/first-cpu-idle',
Expand Down Expand Up @@ -389,6 +390,7 @@ const defaultConfig = {
{id: 'interactive', weight: 5, group: 'metrics'},
{id: 'first-cpu-idle', weight: 2, group: 'metrics'},
{id: 'max-potential-fid', weight: 0, group: 'metrics'},
{id: 'cumulative-layout-shift', weight: 0}, // intentionally left out of metrics so it won't be displayed
{id: 'estimated-input-latency', weight: 0}, // intentionally left out of metrics so it won't be displayed
{id: 'total-blocking-time', weight: 0}, // intentionally left out of metrics so it won't be displayed
{id: 'render-blocking-resources', weight: 0, group: 'load-opportunities'},
Expand Down
3 changes: 3 additions & 0 deletions lighthouse-core/gather/driver.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,9 @@ class Driver {
// Used instead of 'toplevel' in Chrome 71+
'disabled-by-default-lighthouse',

// Used for Cumulative Layout Shift metric
'loading',
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how beefy is this category?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

3% on a verge trace. not bad

image

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why you hoarding this script paul

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/* eslint-disable */
'use strict';

const trace = require('../latest-run/defaultPass.trace.json');
const {traceCategories} = require('../lighthouse-core/gather/driver');

const traceCats = {};
// aggregate
let totalBytes = 0;
let totalEvents = 0;

trace.traceEvents.forEach(e => {
  let eventCats = e.cat;
  for (let eventCat of eventCats.split(',')) {
    // don't process cats we dont trace
    // if (!traceCategories.includes(eventCat)) return;
    if (e.name === 'ThreadControllerImpl::RunTask') eventCat += '::::::::RunTask';
    const cat = traceCats[eventCat] || {bytes: 0, events: 0};
    const bytes = JSON.stringify(e).length;
    cat.bytes += bytes;
    totalBytes += bytes;
    cat.events += 1;
    totalEvents += 1;
    traceCats[eventCat] = cat;
  }
});




// obj to array
const traceTotals = [];
Object.keys(traceCats).forEach(catname => {
	const cat = traceCats[catname];
	traceTotals.push({name: catname, bytes: cat.bytes, events: cat.events});
});

// sort and log
console.log('Bytes'.padStart(16), '\t', 'Count'.padStart(7), '\t', 'Event Name'.padStart(18))
traceTotals.sort((a, b) => b.bytes - a.bytes).forEach((tot, i) => {
	console.log(
    tot.bytes.toLocaleString().padStart(15), 
    `${(tot.bytes * 100/ totalBytes).toLocaleString(undefined, {maximumFractionDigits: 1})}%`.padStart(6),
    '\t', 
    tot.events.toString().padStart(9), 
    `${(tot.events * 100/ totalEvents).toLocaleString(undefined, {maximumFractionDigits: 1})}%`.padStart(6),
    '\t', 
    tot.name
  );
})


// All compile/execute events are captured by parent events in devtools.timeline..
// But the v8 category provides some nice context for only <0.5% of the trace size
'v8',
Expand Down
6 changes: 6 additions & 0 deletions lighthouse-core/lib/i18n/locales/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -839,6 +839,12 @@
"lighthouse-core/audits/manual/pwa-page-transitions.js | title": {
"message": "Page transitions don't feel like they block on the network"
},
"lighthouse-core/audits/metrics/cumulative-layout-shift.js | description": {
"message": "The more the page's layout changes during its load, the higher the Cumulative Layout Shift. Perfectly solid == 0. Unpleasant experience >= 0.50."
},
"lighthouse-core/audits/metrics/cumulative-layout-shift.js | title": {
"message": "Cumulative Layout Shift"
},
"lighthouse-core/audits/metrics/estimated-input-latency.js | description": {
"message": "Estimated Input Latency is an estimate of how long your app takes to respond to user input, in milliseconds, during the busiest 5s window of page load. If your latency is higher than 50 ms, users may perceive your app as laggy. [Learn more](https://web.dev/estimated-input-latency)."
},
Expand Down
6 changes: 6 additions & 0 deletions lighthouse-core/lib/i18n/locales/en-XL.json
Original file line number Diff line number Diff line change
Expand Up @@ -839,6 +839,12 @@
"lighthouse-core/audits/manual/pwa-page-transitions.js | title": {
"message": "P̂áĝé t̂ŕâńŝít̂íôńŝ d́ôń't̂ f́êél̂ ĺîḱê t́ĥéŷ b́l̂óĉḱ ôń t̂h́ê ńêt́ŵór̂ḱ"
},
"lighthouse-core/audits/metrics/cumulative-layout-shift.js | description": {
"message": "T̂h́ê ḿôŕê t́ĥé p̂áĝé'ŝ ĺâýôút̂ ćĥán̂ǵêś d̂úr̂ín̂ǵ ît́ŝ ĺôád̂, t́ĥé ĥíĝh́êŕ t̂h́ê Ćûḿûĺât́îv́ê Ĺâýôút̂ Śĥíf̂t́. P̂ér̂f́êćt̂ĺŷ śôĺîd́ == 0. Ûńp̂ĺêáŝán̂t́ êx́p̂ér̂íêńĉé >= 0.50."
},
"lighthouse-core/audits/metrics/cumulative-layout-shift.js | title": {
"message": "Ĉúm̂úl̂át̂ív̂é L̂áŷóût́ Ŝh́îf́t̂"
},
"lighthouse-core/audits/metrics/estimated-input-latency.js | description": {
"message": "Êśt̂ím̂át̂éd̂ Ín̂ṕût́ L̂át̂én̂ćŷ íŝ án̂ éŝt́îḿât́ê óf̂ h́ôẃ l̂ón̂ǵ ŷóûŕ âṕp̂ t́âḱêś t̂ó r̂éŝṕôńd̂ t́ô úŝér̂ ín̂ṕût́, îń m̂íl̂ĺîśêćôńd̂ś, d̂úr̂ín̂ǵ t̂h́ê b́ûśîéŝt́ 5ŝ ẃîńd̂óŵ óf̂ ṕâǵê ĺôád̂. Íf̂ ýôúr̂ ĺât́êńĉý îś ĥíĝh́êŕ t̂h́âń 50 m̂ś, ûśêŕŝ ḿâý p̂ér̂ćêív̂é ŷóûŕ âṕp̂ áŝ ĺâǵĝý. [L̂éâŕn̂ ḿôŕê](https://web.dev/estimated-input-latency)."
},
Expand Down
6 changes: 6 additions & 0 deletions lighthouse-core/lib/lh-error.js
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,11 @@ const ERRORS = {
code: 'NO_LCP',
message: UIStrings.badTraceRecording,
},
/** Layout Shift trace events are found but without data */
LAYOUT_SHIFT_MISSING_DATA: {
code: 'LAYOUT_SHIFT_MISSING_DATA',
message: UIStrings.badTraceRecording,
},

// TTI calculation failures
FMP_TOO_LATE_FOR_FCPUI: {code: 'FMP_TOO_LATE_FOR_FCPUI', message: UIStrings.pageLoadTookTooLong},
Expand Down Expand Up @@ -376,6 +381,7 @@ const ERRORS = {
},

// Hey! When adding a new error type, update lighthouse-result.proto too.
// Only necessary for runtime errors, which come from artifacts or pageLoadErrors.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So this error will never be a runtime error, correct? Or it won't while it is a silent audit and not part of performance?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i wrote this comment idk how it got here in pauls pr :P

Copy link
Collaborator

@connorjclark connorjclark Jan 23, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"this" error? This comment is a continuation of the previous line, and is referring to when proto must be edited. All of these errors are runtime errors.

};

/** @type {Record<keyof typeof ERRORS, LighthouseErrorDefinition>} */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

exports[`Performance: metrics evaluates valid input (with lcp) correctly 1`] = `
Object {
"cumulativeLayoutShift": undefined,
"estimatedInputLatency": 543,
"estimatedInputLatencyTs": undefined,
"firstCPUIdle": 3677,
Expand All @@ -15,6 +16,8 @@ Object {
"largestContentfulPaint": 3343,
"largestContentfulPaintTs": undefined,
"maxPotentialFID": 1336,
"observedCumulativeLayoutShift": undefined,
"observedCumulativeLayoutShiftTs": undefined,
"observedDomContentLoaded": 1513,
"observedDomContentLoadedTs": 713038536140,
"observedFirstContentfulPaint": 1122,
Expand Down Expand Up @@ -45,6 +48,7 @@ Object {

exports[`Performance: metrics evaluates valid input correctly 1`] = `
Object {
"cumulativeLayoutShift": undefined,
"estimatedInputLatency": 78,
"estimatedInputLatencyTs": undefined,
"firstCPUIdle": 3351,
Expand All @@ -58,6 +62,8 @@ Object {
"largestContentfulPaint": undefined,
"largestContentfulPaintTs": undefined,
"maxPotentialFID": 396,
"observedCumulativeLayoutShift": undefined,
"observedCumulativeLayoutShiftTs": undefined,
"observedDomContentLoaded": 560,
"observedDomContentLoadedTs": 225414732309,
"observedFirstContentfulPaint": 499,
Expand Down
3 changes: 3 additions & 0 deletions lighthouse-core/test/computed/metrics/timing-summary-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ describe('Timing summary', () => {

expect(result.metrics).toMatchInlineSnapshot(`
Object {
"cumulativeLayoutShift": undefined,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would be nice to have at least one trace with this event in there as a test that isn't sample-json

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good call. i got this pending in a followup to simplify.

"estimatedInputLatency": 77.79999999999995,
"estimatedInputLatencyTs": undefined,
"firstCPUIdle": 3351.3320000492968,
Expand All @@ -31,6 +32,8 @@ Object {
"largestContentfulPaint": undefined,
"largestContentfulPaintTs": undefined,
"maxPotentialFID": 396.0000000000001,
"observedCumulativeLayoutShift": undefined,
"observedCumulativeLayoutShiftTs": undefined,
"observedDomContentLoaded": 560.294,
"observedDomContentLoadedTs": 225414732309,
"observedFirstContentfulPaint": 498.87,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14507,6 +14507,7 @@
{"pid":75994,"tid":17667,"ts":185608247189,"ph":"X","cat":"toplevel","name":"MessageLoop::RunTask","args":{"src_file":"../../ipc/ipc_mojo_bootstrap.cc","src_func":"SendMessage"},"dur":30,"tdur":29,"tts":78797},

{"_comment": "Manually added event to make sample lhr not error", "name":"largestContentfulPaint::Candidate", "pid":75994,"tid":17667,"ts":185608247190,"ph":"R","cat":"loading,rail,devtools.timeline", "args": {"frame": "0x44d2861df8"}},
{"_comment": "Manually added event to make test CLS", "name":"LayoutShift", "pid":75994,"tid":775,"ts":185608247190,"ph":"R","cat":"loading,rail,devtools.timeline", "args": {"frame": "0x44d2861df8", "data": {"is_main_frame": true, "cumulative_score": 0.42}}},

{"pid":75994,"tid":17667,"ts":185608250604,"ph":"X","cat":"toplevel","name":"MessagePumpLibevent::OnLibeventNotification","args":{"src_file":"../../mojo/edk/system/channel_posix.cc","src_func":"StartOnIOThread"},"dur":29,"tdur":30,"tts":78849},
{"pid":75994,"tid":17667,"ts":185608250671,"ph":"X","cat":"toplevel","name":"MessagePumpLibevent::OnLibeventNotification","args":{"src_file":"../../mojo/edk/system/channel_posix.cc","src_func":"StartOnIOThread"},"dur":25,"tdur":25,"tts":78903},
Expand Down
40 changes: 40 additions & 0 deletions lighthouse-core/test/results/sample_v2.json
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,23 @@
"numericValue": 122.537,
"displayValue": "120 ms"
},
"cumulative-layout-shift": {
"id": "cumulative-layout-shift",
"title": "Cumulative Layout Shift",
"description": "The more the page's layout changes during its load, the higher the Cumulative Layout Shift. Perfectly solid == 0. Unpleasant experience >= 0.50.",
"score": 0.59,
"scoreDisplayMode": "numeric",
"numericValue": 0.42,
"displayValue": "0.42",
"details": {
"type": "debugdata",
"items": [
{
"finalLayoutShiftTraceEventFound": true
}
]
}
},
"errors-in-console": {
"id": "errors-in-console",
"title": "Browser errors were logged to the console",
Expand Down Expand Up @@ -1271,6 +1288,7 @@
"estimatedInputLatency": 16,
"totalBlockingTime": 117,
"maxPotentialFID": 123,
"cumulativeLayoutShift": 0,
"observedNavigationStart": 0,
"observedNavigationStartTs": 185603319912,
"observedFirstPaint": 3969,
Expand Down Expand Up @@ -3528,6 +3546,10 @@
"weight": 0,
"group": "metrics"
},
{
"id": "cumulative-layout-shift",
"weight": 0
},
{
"id": "estimated-input-latency",
"weight": 0
Expand Down Expand Up @@ -4475,6 +4497,18 @@
"duration": 100,
"entryType": "measure"
},
{
"startTime": 0,
"name": "lh:audit:cumulative-layout-shift",
"duration": 100,
"entryType": "measure"
},
{
"startTime": 0,
"name": "lh:computed:CumulativeLayoutShift",
"duration": 100,
"entryType": "measure"
},
{
"startTime": 0,
"name": "lh:audit:errors-in-console",
Expand Down Expand Up @@ -5506,6 +5540,12 @@
"lighthouse-core/audits/metrics/max-potential-fid.js | description": [
"audits[max-potential-fid].description"
],
"lighthouse-core/audits/metrics/cumulative-layout-shift.js | title": [
"audits[cumulative-layout-shift].title"
],
"lighthouse-core/audits/metrics/cumulative-layout-shift.js | description": [
"audits[cumulative-layout-shift].description"
],
"lighthouse-core/audits/errors-in-console.js | failureTitle": [
"audits[errors-in-console].title"
],
Expand Down
Loading