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

report: DRY up audit & opportunity rendering #5136

Merged
merged 9 commits into from
May 17, 2018
Merged

Conversation

paulirish
Copy link
Member

@paulirish paulirish commented May 6, 2018

Gets rid of a lot of duplicated work, and brings a lovely consistency to the styles.

https://lighthouse-oppoasanaudit.now.sh/

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.

not 100% sure what this buys us functionality-wise, slightly nervous we'll get fancier with the opportunities and need to fork again, but I'm probably missing the grand vision


// Don't mutate the value
displayValue = [...displayValue];
Copy link
Collaborator

Choose a reason for hiding this comment

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

oh heh, I guess we might want to use them more than once huh :) thanks for the cleanup!

wanna just remove the mutations? const template = displayValue[0]; ... of displayValue.slice(1)

Copy link
Member

Choose a reason for hiding this comment

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

add a util-test.js test for mutation?

* @return {!Element}
*/
renderAudit(audit, index) {
const tmpl = this.dom.cloneTemplate('#tmpl-lh-audit', this.templateContext);
renderAudit(audit, index, providedTmpl) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

feels like this sorta becomes populateAuditValues instead, is that fair?

Copy link
Member Author

Choose a reason for hiding this comment

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

essentially yeah.

this.dom.find('.lh-sparkline__bar', element).style.width = sparklineWidthPct;
wastedEl.textContent = Util.formatSeconds(summaryInfo.wastedMs, 0.01);

if (audit.result.displayValue) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

so if we're overriding displayValue anyhow and there's no helpText, we're using renderAudit for

  • populating index
  • setting rating class
  • sticking it inside of details
  • filling error/debugString
  • something else I'm missing?

WDYT about extracting those 4 to a method they both share?

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 the sound of that. will do.

.lh-audit__header:hover {
background-color: #F8F9FA;
}


.lh-audit-group[open] > .lh-audit-group__summary > .lh-toggle-arrow,
.lh-expandable-details[open] > .lh-expandable-details__summary > .lh-toggle-arrow,
.lh-expandable-details[open] > .lh-expandable-details__summary > div > .lh-toggle-arrow {
.lh-expandable-details[open] > .lh-expandable-details__summary > div > .lh-toggle-arrow,
.lh-expandable-details[open] > .lh-expandable-details__summary > div > div > .lh-toggle-arrow {
Copy link
Collaborator

Choose a reason for hiding this comment

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

the nest grows deeper :( removed in chevron ✨ though?

Copy link
Member Author

Choose a reason for hiding this comment

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

yah in #5137 this gets cleaned up a lot.

@paulirish
Copy link
Member Author

not 100% sure what this buys us functionality-wise, slightly nervous we'll get fancier with the opportunities and need to fork again, but I'm probably missing the grand vision

There's been a lot of bugs and inconsistencies recently between opps and audits, all stemming from their separate implementations:

  1. opps's toggle-arrow wasn't animating
  2. error'd opps werent being handled the same as error'd audits. They needed the "Error!" displaytext + tooltip.
  3. Different margin/paddings all around. around the description. on the left/right side of the details tables.
  4. debugString placement was different

(To be fair, all these are my fault, but all of these made it past review into master, so... they're sneaky)

In what I have here the templates are defined separately, we're just using the same classes for all the same things. And so we improve maintainability and reduce the duplication.
➡️ ➡️ ➡️ image

net negative what what

@patrickhulce
Copy link
Collaborator

There's been a lot of bugs and inconsistencies recently between opps and audits, all stemming from their separate implementations

cool cool, yeah sg with your planned changes 👍

@@ -15,8 +15,8 @@ class FirstMeaningfulPaint extends Audit {
static get meta() {
return {
name: 'first-meaningful-paint',
description: 'First meaningful paint',
helpText: 'First meaningful paint measures when the primary content of a page is visible. ' +
description: 'First Meaningful Paint',
Copy link
Member

Choose a reason for hiding this comment

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

is it possible to squash/rebase/something off of #5130? definitely confusing having all of that in here when it's going to merge with 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.

rebased. much cleaner.

* @return {!Element}
*/
renderAudit(audit, index) {
const tmpl = this.dom.cloneTemplate('#tmpl-lh-audit', this.templateContext);
renderAudit(audit, index, providedTmpl) {
Copy link
Member

Choose a reason for hiding this comment

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

docstring would be good to explain that you can provide an alternative template, just needs to match #tmpl-lh-audit in structures a, b, and c


// Don't mutate the value
displayValue = [...displayValue];
Copy link
Member

Choose a reason for hiding this comment

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

add a util-test.js test for mutation?

@paulirish paulirish changed the base branch from metricsdisplay to metricsdisplay-oldrebase May 7, 2018 19:21
@paulirish paulirish changed the base branch from metricsdisplay-oldrebase to master May 8, 2018 03:56
@paulirish paulirish changed the title report: render opportunities as a subclass of audits report: DRY up audit & opportunity rendering May 12, 2018
@paulirish
Copy link
Member Author

(this is ready for another look)

Copy link
Member

@brendankenny brendankenny left a comment

Choose a reason for hiding this comment

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

this seems like a good direction to go for now. Dedupes error-prone stuff but still easily separable if they need to go their own ways in the future

const auditEl = this.dom.find('.lh-audit', tmpl);
auditEl.id = audit.result.id;
const displayTextEl = this.dom.find('.lh-audit__display-text', auditEl);
Copy link
Member

Choose a reason for hiding this comment

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

nit: move this into the conditional where it's used?

element.classList.add(`lh-load-opportunity--${Util.calculateRating(audit.result.score)}`);
const oppTmpl = this.dom.cloneTemplate('#tmpl-lh-opportunity', this.templateContext);
const element = this.populateAuditValues(audit, index, oppTmpl);
element.classList.add(`lh-audit--${Util.calculateRating(audit.result.score)}`);
Copy link
Member

Choose a reason for hiding this comment

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

looks like this is now already set in populateAuditValues by _setRatingClass()

Copy link
Member

Choose a reason for hiding this comment

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

lol populateAuditValues also has a stray auditEl.classList.add(lh-audit--${audit.result.scoreDisplayMode}); line right before calling _setRatingClass

Copy link
Member Author

Choose a reason for hiding this comment

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

hah. thanks for catching both of these

const detailsElem = this.detailsRenderer.render(details);
detailsElem.classList.add('lh-details');
element.appendChild(detailsElem);
const wastedEl = this.dom.find('.lh-audit__display-text', element);
Copy link
Member

Choose a reason for hiding this comment

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

maybe comment that everything below here is overwriting the default displayValue display provided by populateAuditValues with opportunity-specific stuff?

wastedEl.textContent = Util.formatSeconds(summaryInfo.wastedMs, 0.01);
}

if (audit.result.displayValue) {
Copy link
Member

Choose a reason for hiding this comment

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

this seems weird to do if it was an error scoreDisplayMode. Should be nested inside above error conditional?

Copy link
Member Author

Choose a reason for hiding this comment

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

thanks. didnt need the error conditional after all.

return this.populateAuditValues(audit, index, tmpl);
}

/**
Copy link
Member

Choose a reason for hiding this comment

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

still want a docstring here :P

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

Copy link
Member

@brendankenny brendankenny left a comment

Choose a reason for hiding this comment

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

last questions :)

},
};

const fakeCategory = Object.assign({}, category, {auditRefs: [auditWithDebug]});
const categoryDOM = renderer.render(fakeCategory, sampleResults.categoryGroups);

const debugEl = categoryDOM.querySelector('.lh-load-opportunity .lh-debug');
const debugEl = categoryDOM.querySelector('.lh-audit--load-opportunity .lh-debug');
Copy link
Member

Choose a reason for hiding this comment

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

maybe call this tooltipEl? (at least I believe that's what it selects now)

@@ -71,7 +81,7 @@ class CategoryRenderer {
const textEl = this.dom.find('.lh-audit__display-text', auditEl);
textEl.textContent = 'Error!';
textEl.classList.add('tooltip-boundary');
const tooltip = this.dom.createChildOf(textEl, 'div', 'lh-error-tooltip-content tooltip');
const tooltip = this.dom.createChildOf(textEl, 'div', 'tooltip lh-debug');
Copy link
Member

Choose a reason for hiding this comment

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

does it make sense for the tooltip to share the lh-debug class?

Copy link
Member Author

Choose a reason for hiding this comment

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

yes

detailsElem.classList.add('lh-details');
element.appendChild(detailsElem);
this.dom.find('.lh-sparkline__bar', element).style.width = sparklineWidthPct;
displayEl.textContent = Util.formatSeconds(summaryInfo.wastedMs, 0.01);
Copy link
Member

Choose a reason for hiding this comment

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

feels weird to overwrite Error! with this in the error case. Will it always have a summaryInfo if there was a gatherer or audit error?

Copy link
Member

@brendankenny brendankenny left a comment

Choose a reason for hiding this comment

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

LGTMMM

@paulirish paulirish merged commit a99c07b into master May 17, 2018
@paulirish
Copy link
Member Author

I want to thank the Academy, my wife, Daisy the donkey, and big G.

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