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

core(lhr): migrate opportunity details to new format #5296

Merged
merged 11 commits into from
May 25, 2018
Merged

Conversation

brendankenny
Copy link
Member

@brendankenny brendankenny commented May 22, 2018

part of #5008

Moves opportunity details over to the new format. Wanted to get feedback before changing the many tests that are failing due to the slightly different details shape.

Most of the byte efficiency audit changes are just name changes, e.g. results->items, itemType->valueType.

Shape of the new opportunity details is what's in lhr-lite:

export interface OpportunityDetails {
type: 'opportunity';
overallSavingsMs: number
overallSavingsBytes?: number
headings: ColumnHeading[];
items: (WastedBytesDetailsItem | WastedTimeDetailsItem)[];
}

with the addition of more possibilities in OpportunityDetailsItem than is in the more limited lhr-lite.

* @param {number=} overallSavingsBytes
* @return {LH.Result.Audit.OpportunityDetails}
*/
static makeOpportunityDetails(headings, items, overallSavingsMs, overallSavingsBytes) {
Copy link
Member Author

Choose a reason for hiding this comment

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

there's no real reason this needs to be a thing, we just need a place to check that audits are returning the correct shape. If we start enforcing the return type of audits based on the details they provide (e.g. @return {LH.Audit.Result<OpportunityDetails>} or whatever) that could work just as well.

@@ -242,6 +244,79 @@ class DetailsRenderer {
return tableElem;
}

/**
Copy link
Member Author

Choose a reason for hiding this comment

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

this is called _renderOpportunityTable for now, but I'd like to migrate all audits with table details to this one and eventually just have it be _renderTable. The changes from the original mean we only have so many types of things that can fit in the table cells, so just call them out explicitly instead of having nested details that can themselves contain more details, etc.

E.g. here we get rid of the "URLs" that are actually {type: 'code', value: txt}, and instead just say if it doesn't look like a URL, render it in <pre></pre> tags

Copy link
Collaborator

@patrickhulce patrickhulce May 22, 2018

Choose a reason for hiding this comment

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

I like this. Does this mean we'd eliminate the fallbackType/fallbackKey approach? Also this method feels a bit long, want to break it up? :)

Copy link
Member Author

Choose a reason for hiding this comment

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

I like this. Does this mean we'd eliminate the fallbackType/fallbackKey approach?

I guess it comes down to how flexible we need it to end up being. It doesn't seem like we have a ton of cases where we need fallbacks, so we can probably get by with using hybrid valueTypes, like url is here (maybe we'd want to rename them based on their actual combined type? e.g. 'urlOrCode', but something better :)

Copy link
Member

Choose a reason for hiding this comment

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

can you add a comment with this todo?

Copy link
Collaborator

@patrickhulce patrickhulce left a comment

Choose a reason for hiding this comment

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

I think this all looks good to me! all seems to be in line with what we planned other than the fallback* issue, but I like the new version if we can get away with it

case 'node':
return this.renderNode(/** @type {NodeDetailsJSON} */(details));
case 'criticalrequestchain':
return CriticalRequestChainRenderer.render(this._dom, this._templateContext,
// @ts-ignore - TODO(bckenny): Fix type hierarchy
/** @type {CRCDetailsJSON} */ (details));
case 'opportunity':
// @ts-ignore - TODO(bckenny): Fix type hierarchy
return this._renderTable(/** @type {OpportunityDetails} */ (details));
Copy link
Collaborator

Choose a reason for hiding this comment

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

render opportunity table?

"type": "table",
"headings": [],
"type": "opportunity",
"headings": [
Copy link
Collaborator

Choose a reason for hiding this comment

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

seems like we still don't want to populate headings if there are no items

Copy link
Collaborator

Choose a reason for hiding this comment

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

bump

Copy link
Member Author

Choose a reason for hiding this comment

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

seems like we still don't want to populate headings if there are no items

makes me sad but ok

typings/lhr.d.ts Outdated
totalBytes?: number;
wastedMs?: number;
wastedPercent?: number;
fromProtocol?: boolean;
Copy link
Collaborator

Choose a reason for hiding this comment

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

do we want to just nuke these?

Copy link
Member Author

Choose a reason for hiding this comment

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

do we want to just nuke these?

yeah, I was building them up to make sure every case was covered, but probably should just be an index type

Copy link
Member Author

Choose a reason for hiding this comment

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

but probably should just be an index type

turns out it wasn't that simple because we want them to extend lhr-lite, but now an index type + minimum set of properties

Copy link
Member

@paulirish paulirish left a comment

Choose a reason for hiding this comment

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

seems good. a few questions

@@ -81,6 +81,23 @@ declare global {
blockedUrlPatterns: string[];
extraHeaders: Crdp.Network.Headers;
}

export module Audit {
Copy link
Member

Choose a reason for hiding this comment

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

curious why this is in lhr.d.ts instead of audit.d.ts

Copy link
Member Author

Choose a reason for hiding this comment

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

curious why this is in lhr.d.ts instead of audit.d.ts

Like lhr-lite.d.ts, it seems like all the LHR stuff should be defined in lhr.d.ts, instead of spread over lhr.d.ts and audit.d.ts. That would leave audit.d.ts with types internal to operating an audit, while Audit.Result stuff would all be in lhr.d.t.s (with a good chunk of that just inherited from lhr-lite.d.ts).

This starts on that path, plus is a nice dividing line between this finalized-ish details definition vs the handwavey/just-make-it-work definitions in audit.d.ts

@@ -242,6 +244,79 @@ class DetailsRenderer {
return tableElem;
}

/**
Copy link
Member

Choose a reason for hiding this comment

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

can you add a comment with this todo?

default: {
throw new Error(`Unknown type: ${details.type}`);
}
}
}

/**
* @param {NumericUnitDetailsJSON} details
* @param {{value: number, granularity?: number}} details
Copy link
Member

Choose a reason for hiding this comment

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

bytes defaults to granularity of 0.1 in util, so removing the granularity in the audits means these will now show as more precise, right?

dont' we want to keep the granularity the same?

Copy link
Member Author

Choose a reason for hiding this comment

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

bytes defaults to granularity of 0.1 in util, so removing the granularity in the audits means these will now show as more precise, right? dont' we want to keep the granularity the same?

I forget what we decided on granularity for these. Always to 1 or was bytes going to be one of the auto-formatting options?

Copy link
Member

Choose a reason for hiding this comment

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

happy with defaulting opportunity bytes granularity to 1.

@brendankenny
Copy link
Member Author

turns out tests weren't bad, mostly s/results/items and flattening the smoke expectations a bit. Ready for really real review

Copy link
Collaborator

@patrickhulce patrickhulce left a comment

Choose a reason for hiding this comment

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

mostly just the extra headings in the JSON thing, other than that looks good to me!

@@ -55,31 +59,34 @@ class DetailsRenderer {
// @ts-ignore - TODO(bckenny): Fix type hierarchy
return this._renderTable(/** @type {TableDetailsJSON} */ (details));
case 'code':
return this._renderCode(details);
return this._renderCode(/** @type {StringDetailsJSON} */ (details));
Copy link
Collaborator

Choose a reason for hiding this comment

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

if we're killing string details json elsewhere should we be moving this to it?

Copy link
Member Author

Choose a reason for hiding this comment

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

if we're killing string details json elsewhere should we be moving this to it?

I can leave it as DetailsJSON? Basically I need to tell it that it's not an OpportunityDetails, and until all the details types are known to the compiler with type defined it isn't narrowing it down here

Copy link
Collaborator

Choose a reason for hiding this comment

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

Oh I meant elsewhere it seems like we're deleting StringDetailsJSON and going with literal {text: string} typedefs, so should we just do that instead

@@ -842,6 +842,7 @@ summary.lh-passed-audits-summary {

.lh-table-column--text,
.lh-table-column--bytes,
.lh-table-column--timespanMs,
Copy link
Collaborator

Choose a reason for hiding this comment

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

😢 I guess a _.toKebabCase is a bit much huh?

Copy link
Member Author

Choose a reason for hiding this comment

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

I guess a _.toKebabCase is a bit much huh?

ha, that's a good point, but it'd also be pretty ugly. Is the tear because you're accepting living with it or do you really want this?

Copy link
Collaborator

Choose a reason for hiding this comment

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

💦 because I'm living with it :)

const expectedPreview = {type: 'code', value: 'dummy'};
assert.deepEqual(map({header: {sourceURL: ''}}).url, expectedPreview);
assert.deepEqual(map({header: {sourceURL: 'a'}}, 'http://g.co/a').url, expectedPreview);
const expectedPreview ='dummy';
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: space after =

Copy link
Member Author

Choose a reason for hiding this comment

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

what are you doing eslint

"type": "table",
"headings": [],
"type": "opportunity",
"headings": [
Copy link
Collaborator

Choose a reason for hiding this comment

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

bump

@brendankenny
Copy link
Member Author

updated

Copy link
Collaborator

@patrickhulce patrickhulce left a comment

Choose a reason for hiding this comment

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

LGTM! 💯 🆕

* @param {OpportunityDetails} details
* @return {Element}
*/
_renderOpportunityTable(details) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

this fn is a bit long, you foresee breaking it up in the future? add a TODO if so :)

Copy link
Member Author

Choose a reason for hiding this comment

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

done!

{key: 'wastedMs', itemType: 'ms', text: 'Download Time (ms)', granularity: 1},
{key: 'url', valueType: 'url', label: 'URL'},
{key: 'totalBytes', valueType: 'bytes', label: 'Size (KB)'},
{key: 'wastedMs', valueType: 'timespanMs', label: 'Download Time (ms)'},
Copy link
Member

Choose a reason for hiding this comment

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

we'll be dropping granularity of 1 and getting default of 10 afaict.
that is probably fine, but just FYI

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants