Skip to content

Introduces isPWA boolean#2032

Closed
ebidel wants to merge 6 commits intomasterfrom
ispwa
Closed

Introduces isPWA boolean#2032
ebidel wants to merge 6 commits intomasterfrom
ispwa

Conversation

@ebidel
Copy link
Copy Markdown
Contributor

@ebidel ebidel commented Apr 18, 2017

Part of #1937.

Took at stab at this. Right now, it's based off of the pwa category score being 100. Nothing more.

Also added a small UI check if you're "certified". We don't have to do that but I figured people might want to see that in a report.

screen shot 2017-04-18 at 12 56 48 pm

@paulirish paulirish mentioned this pull request Apr 18, 2017
52 tasks
@patrickhulce
Copy link
Copy Markdown
Collaborator

short and sweet I like it, any thoughts on exposing this at the toplevel object vs. in the category? I kinda like it contained within the category but that does mean every consumer has to do results.reportCategories.find(cat => cat.id === 'pwa').isPwa

@ebidel
Copy link
Copy Markdown
Contributor Author

ebidel commented Apr 18, 2017

Yea, it might be easy for consumers to check a top level prop rather than a buried obj.

Either is fine with me.

@ebidel
Copy link
Copy Markdown
Contributor Author

ebidel commented Apr 18, 2017

isPWA is also top level now. Kept it part of the category too so the renderer UI can access it easily instead of poking back at the report. Not thrilled about the duplication though.

Copy link
Copy Markdown
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.

Everything in here is looking on point. V nice.

const element = this._populateScore(
tmpl, score, 'numeric', category.name, category.description);
if (category.isPWA) {
const titleEl = element.querySelector('.lh-score__title');
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

extract this block into a separate method?

@paulirish
Copy link
Copy Markdown
Member

paulirish commented Apr 21, 2017

I want to discuss how we represent the PWA score + passing threshold. My take is we want to reward only the best best apps with a score of 100, to incentivize performance improvements. So we should set the bar for isPWA passing a bit lower.

A wild strawman proposal appears!

Passing isPWA ✓

  • PWA score of 70, isPWA ✓: All PWA audits as passing. (FastEnough audit is passing). The TTI is scoring a 70/100.✜.
  • PWA score of 85, isPWA ✓: Same, but TTI is scoring 85/100.
  • PWA score of 100, isPWA ✓: Same, but TTI is scoring 100/100.

Failing isPWA ✘

  • PWA score of ~63, isPWA ✘: All PWA audits as passing, except for FastEnough audit, which fails as TTI is scoring < 70.
  • PWA scores of 63.8 - 69.9: Impossible. Once you're failing one of the PWA booleans, you're losing full points for that audit. (Currently we're at 11 audits, so each fail is worth ~6.3 pts, assuming even weighting.)

TTI Scoring

✜ TTI scoring has come up a lot, but one solution is: 70/100 is the score for whatever the "fast enough" definition of the baseline checklist says. (Currently its 10s, discussions around it moving to 5s). For example, that scoring curve could look like this: https://www.desmos.com/calculator/whus3whb2i (median at 15.7s, podr at 2s). 70% score at 10s. 80% score at 7.5s. 90% at 5.1s. (All the disclaimers about TTI changing apply here)


what do ya'll think?

@patrickhulce
Copy link
Copy Markdown
Collaborator

Lots to parse in there @paulirish :) but I like the idea of basically saying your final PWA score is min(pwa.score, timeToInteractive.score) but have the boolean still be based on pwa.score === 100

@paulirish
Copy link
Copy Markdown
Member

@brendankenny is gonna iterate on this. we discussed a solution and with some slight changes this will be goooooooood.

@paulirish paulirish requested a review from brendankenny April 22, 2017 00:58
@ebidel
Copy link
Copy Markdown
Contributor Author

ebidel commented Apr 25, 2017

@brendankenny are you going add to this PR? Not sure what was discussed :)

@brendankenny
Copy link
Copy Markdown
Contributor

yeah, I'm going to adapt it. Plan is basically just a new thing in config to make the check more detailed but also separate from category score. Should hit most of what we want and give us flexibility if we decide to use a different approach later

@brendankenny brendankenny self-assigned this Apr 25, 2017
@paulirish paulirish mentioned this pull request May 5, 2017
40 tasks
@ebidel
Copy link
Copy Markdown
Contributor Author

ebidel commented May 16, 2017

@brendankenny do you think we'll land this for IO?

@brendankenny
Copy link
Copy Markdown
Contributor

added "certifications" to the config, allowing scoring of a category to be independent of the certification of it. e.g. a site can be ✔PWA but we still give them a bad score cause they're really slow or whatever.

Uses the same styling as before (just a green check).

Wanted to get implementation feedback before adding tests.

});

// Validate certification (if any).
if (category.certification) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

do we want to validate any certification in the config, even if a category doesn't call it out?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

do we want to validate any certification in the config

like just check that the audits a certification is requesting will be run? We could do that, but I'm already running into issues with filtering the config with onlyAudits. For this version of validation, I was going to drop the certification property if onlyAudits filtered out a required audit rather than show an error. If we want to validate any certification in the config, I'm not sure what to do in that case...strip out the certification altogether?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

i see.

okay then. this works for me.

pwaCategory.isPWA = isPWA;
}
// Check certification (if any).
let certified;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

isCertified

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

done

@paulirish
Copy link
Copy Markdown
Member

paulirish commented May 16, 2017

I had envisioned a slight tweak on this, but lmk wyt:

  • the LHR has a certifications object
  • within that object is a isCertified boolean
  • and the reportCategory references that certification by ID.

but no strong feelings. And this approach may be not in-line with how we do report* in the LHR now.

Copy link
Copy Markdown
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.

It seems like the only connection certifications have with categories is we want a particular certification to be displayed in the report as a checkmark on a particular category header, is there a different way to model this so certifications appear more as a standalone thing?

For example it feels weird that we'll be returning a reportCertifications object that does not have a isCertified/passed property and you have to comb through the categories to match it up and find out if it passed.

return this._groups;
}

/** @type {Object<string, {title: string, description: string}>|undefined} */
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

this type doesn't look right?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

no, that's a c/p mistake

"name": "Progressive Web App",
"weight": 1,
"description": "These audits validate the aspects of a Progressive Web App, as specified by the baseline [PWA Checklist](https://developers.google.com/web/progressive-web-apps/checklist).",
"certification": "is-pwa",
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

why is it a property of a category? there seems to be no relationship at all to the category shouldn't certifications just be evaluated and returned as their own thing?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

why is it a property of a category?

does Paul's idea sound good to you? Top level evaluated certifications, and a category can say, "hey, put a checkmark next to me based on if the certification with this name passed"?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

sgtm for now ya 👍

const element = this._populateScore(
tmpl, score, 'numeric', category.name, category.description);

if (certDefinitions && category.certification && category.isCertified) {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

someone once told me we should trust our closure types and not be defensive beyond them... ;)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

but, backwards compat? shrug

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

haha I agree @paulirish! just wanted to point it out to those who were down on it to give me some slack :P

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

backwards compat

hehe, no :P

In this case certDefinitions is an optional argument (though arguably perf and a11y categories should get it too), a category might not have a certification, and we only add a check mark if the category is certified...there's no red x for failing certification

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

perf and a11y categories should get it too

er, perf and a11y category renderers should get it too

if (category.certification) {
// Certification and required audits existence checked by Config.
const certification = config.certifications[category.certification];
isCertified = certification.audits.reduce((result, certAudit) => {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

nit: I think Paul is not a reduce fan, could just use .every instead

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

i'm okay with it here. (as it is reducing down to a single value, rather than pushing items onto an array).

but now that you mention it, every() seems better. :)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

every is nice

@brendankenny
Copy link
Copy Markdown
Contributor

ok, so I think I like the idea of structural certifications, where certifications exist independent of categories, and they pass if the audits in question meet a threshold.

Questions:

  • how to deal with blacklisting things via onlyAudits or onlyCategories? Audits will be removed, and suddenly certifications won't be able to pass?
  • do we care about failing certifications? One way to fix the above is a LHR either gets a certification or it does't, and "doesn't" may include not meeting minimum scores (failing) or the audit(s) in question never ran
  • How do we deal with config error checking? Hard fail upon referencing audits that don't exist is ideal, but if we go with the above, we're going to have to allow references to audits that don't exist in the config, which isn't ideal. Easy to miss a misspelled audit name and that a certification just never passes

@patrickhulce
Copy link
Copy Markdown
Collaborator

how to deal with blacklisting things via onlyAudits or onlyCategories? Audits will be removed, and suddenly certifications won't be able to pass?

How do we deal with config error checking? Hard fail upon referencing audits that don't exist is ideal, but if we go with the above, we're going to have to allow references to audits that don't exist in the config, which isn't ideal. Easy to miss a misspelled audit name and that a certification just never passes

I'd say we just filter out certifications that can't be met by the result of onlyAudits/onlyCategories when we're doing the filtering stage, that way we still hard fail for misspellings and such but only run certifications when we actually can.

do we care about failing certifications? One way to fix the above is a LHR either gets a certification or it does't, and "doesn't" may include not meeting minimum scores (failing) or the audit(s) in question never ran

IMO we should just provide them in the results JSON for now and special case the is-pwa and future is-exemplary-pwa for display as checkmarks in particular places.

Later on certifications could each appear as nav items to click and visit an overview page for that certification that shows the failures/what comprises the audit/whatever we want

@brendankenny
Copy link
Copy Markdown
Contributor

updated to top level certifications. Like 15 extending corner cases to still test, tho

Copy link
Copy Markdown
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 like this a lot, feels much more extensible in the exemplary/distinguished/baller designations to come :)

if (certification.isCertified) {
const titleEl = element.querySelector('.lh-score__title');
const link = /** @type {!Element} */ (titleEl.appendChild(this._dom.createSpanFromMarkdown(
`[✔](${certification.url})`)));
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

should we put an x if it didn't meet the requirements?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

nah.

const titleEl = element.querySelector('.lh-score__title');
const link = /** @type {!Element} */ (titleEl.appendChild(this._dom.createSpanFromMarkdown(
`[✔](${certification.url})`)));
link.classList.add('lh-score__isCertified');
Copy link
Copy Markdown
Collaborator

@patrickhulce patrickhulce May 17, 2017

Choose a reason for hiding this comment

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

nit: __certification or maybe --certified on lh-score? at the very least __is-certified :)

}

function validateCategories(categories, audits, auditResults, groups) {
function validateCategories(categories, audits, auditResults, groups, certifications) {
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

add docs

});
}

function validateCertifications(certifications, audits, auditResults) {
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

add docs

* @return {!Element}
*/
render(category, groups) {
render(category, groups, certifications) {
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I've been thinking that we should be passing the report object around instead of adding additional params to all of the render methods + piping it throughout. Each method can pull the properties it cares about. WDYT?

@ebidel ebidel added #BOB and removed rls blocker labels Jun 23, 2017
@paulirish
Copy link
Copy Markdown
Member

Once this boolean (via whitelisting) is in place, then we can move manifest-name-short-enough from Best Practices into PWA

@paulirish
Copy link
Copy Markdown
Member

No more demand for this fella it seems.

As of May, a 100 PWA score === this checkmark. We don't see that changing in the short term.

@paulirish paulirish closed this Oct 12, 2017
@paulirish paulirish deleted the ispwa branch October 12, 2017 00:01
@brendankenny
Copy link
Copy Markdown
Contributor

🎉 🎂

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.

4 participants