Conversation
| if (!isFast) { | ||
| return LoadFastEnough4Pwa.generateAuditResult({ | ||
| rawValue: false, | ||
| debugString: `Under mobile conditions, the TTI was at ${ttiResult.displayValue}. ` + |
There was a problem hiding this comment.
do we need a debug string here?
also feels a little weird we're asserting here that everything was under mobile conditions when we don't really know it was :) thoughts on adding some fancy check for network throughput AND TTI matching certain conditions?
There was a problem hiding this comment.
Very good point. I'd hate for people to setup a CI, leave off emulation, and always pass this audit.
There was a problem hiding this comment.
Should there be a unit after ${ttiResult.displayValue}?
|
|
||
| return FastPWAAudit.audit(generateArtifactsWithTrace(traceEvents)).then(result => { | ||
| assert.equal(result.rawValue, false, 'not failing a long TTI value'); | ||
| TTIAudit.audit = origTTI; |
There was a problem hiding this comment.
will this mess anything else up if it fails? should we restore original method in catch too?
There was a problem hiding this comment.
Was thinking about that! Maybe move to before each etc..
There was a problem hiding this comment.
another reason why we need randomized test order :)
| if (!isFast) { | ||
| return LoadFastEnough4Pwa.generateAuditResult({ | ||
| rawValue: false, | ||
| debugString: `Under mobile conditions, the TTI was at ${ttiResult.displayValue}. ` + |
There was a problem hiding this comment.
Should there be a unit after ${ttiResult.displayValue}?
| return LoadFastEnough4Pwa.generateAuditResult({ | ||
| rawValue: false, | ||
| debugString: `Under mobile conditions, the TTI was at ${ttiResult.displayValue}. ` + | ||
| 'More details in "Performance" section.', |
There was a problem hiding this comment.
fancy link? More details in ["Performance" section](#performance).
There was a problem hiding this comment.
can't do markdown in debugText. can only do it in helpText. :/
There was a problem hiding this comment.
and displayValue already has a unit in it. :)
| @@ -0,0 +1,62 @@ | |||
| /** | |||
| * @license Copyright 2017 Google Inc. All Rights Reserved. | |||
There was a problem hiding this comment.
but for reals, I think we should have one style or the other, and not mix them based on who wrote the file :)
There was a problem hiding this comment.
i am very happy to change the codebase in one full sweep.
There was a problem hiding this comment.
i am very happy to change the codebase in one full sweep.
sounds perfect for another PR :P
|
|
||
| return FastPWAAudit.audit(generateArtifactsWithTrace(traceEvents)).then(result => { | ||
| assert.equal(result.rawValue, false, 'not failing a long TTI value'); | ||
| TTIAudit.audit = origTTI; |
There was a problem hiding this comment.
another reason why we need randomized test order :)
| // https://developers.google.com/web/progressive-web-apps/checklist | ||
| const MAXIMUM_TTI = 10 * 1000; | ||
|
|
||
| class LoadFastEnough4Pwa extends Audit { |
| 'use strict'; | ||
|
|
||
| const Audit = require('./audit'); | ||
| const TTIMetric = require('./time-to-interactive'); |
There was a problem hiding this comment.
we should really just make a "page timing" computed artifact and move both FMP and TTI in there
There was a problem hiding this comment.
Yeah I have need for it now too in OffscreenImages thanks to @brendankenny obnoxiously useful suggestion :P
There was a problem hiding this comment.
TBH i think audits depending on audits is almost the same as computed artifacts depending on eachother.
and i'm kinda less interested in making one big "page timing" one, as it'd have to run TTI tracing model stuff even if you only want FMP.
There was a problem hiding this comment.
but now don't we have to run the TTI tracing model stuff 3x instead of just once?
There was a problem hiding this comment.
gotta rerun parts of it, but the tracing model is a comptued artifact.
i profiled a run and reruning the TTI.audit() probably is like 3ms max, but we have like 6000ms of main thread time total.
| const mockTTIResult = {extendedInfo: {value: {timings: {timeToInteractive: 15000}}}}; | ||
| TTIAudit.audit = _ => Promise.resolve(mockTTIResult); | ||
|
|
||
| return FastPWAAudit.audit(generateArtifactsWithTrace(traceEvents)).then(result => { |
There was a problem hiding this comment.
why not just pass a trace in? If there was a trace with one really really long top level event it should fail the test :)
| }); | ||
| }); | ||
|
|
||
| it('fails a bad TTI value', () => { |
There was a problem hiding this comment.
add a quick test for the network case?
| category: 'PWA', | ||
| name: 'load-fast-enough-for-pwa', | ||
| description: 'Page load is fast enough on 3G', | ||
| helpText: 'Satisfied if the _Time To Interactive_ duration is shorter than _10 seconds_, as defined by the [PWA Baseline Checklist](https://developers.google.com/web/progressive-web-apps/checklist).', |
There was a problem hiding this comment.
maybe add a note here too that emulation must be enabled?
| @@ -0,0 +1,62 @@ | |||
| /** | |||
| * @license Copyright 2017 Google Inc. All Rights Reserved. | |||
There was a problem hiding this comment.
but for reals, I think we should have one style or the other, and not mix them based on who wrote the file :)
| static audit(artifacts) { | ||
| const networkRecords = artifacts.networkRecords[Audit.DEFAULT_PASS]; | ||
| const allRequestLatencies = networkRecords.map(record => { | ||
| if (!record._timing) return Infinity; |
There was a problem hiding this comment.
why default with Infinity and not e.g. 0?
There was a problem hiding this comment.
because if there is no timing data on a request then we don't care about it. we don't want to consider it for this analysis.
i'm also happy to filter netRecords to only the ones with timing first.
There was a problem hiding this comment.
or alternatively the allRequestLatencies.every(val => val > latency3gMin) thing will return true if val is undefined.
There was a problem hiding this comment.
definitely don't want to depend on implicit NaN behavior. I was just wondering, but filtering does sound like it might be clearer (plus Infinity doesn't make it through JSON.stringify(), so it makes sense if including the latencies in the extendedInfo)
|
|
||
| const extendedInfo = { | ||
| formatter: Formatter.SUPPORTED_FORMATS.NULL, | ||
| value: {allRequestLatencies, timeToInteractive} |
There was a problem hiding this comment.
do we care about having either one of these in the extended info? timeToInteractive may make sense, I guess (e.g. if you run the PWA checks but not the perf ones), but probably not the latencies
There was a problem hiding this comment.
shrugs.
i am just thinking that people will probably want to debug failures here ( in case throttling messed up or they are trying to use diff throttling or real cellular )...
and if we know that A BUNCH of their reqs were slow enough but 1 had a latency that barely missed things, then we can change our policy here.
There was a problem hiding this comment.
i am just thinking that people will probably want to debug failures here ( in case throttling messed up or they are trying to use diff throttling or real cellular )...
and if we know that A BUNCH of their reqs were slow enough but 1 had a latency that barely missed things, then we can change our policy here.
OTOH things only get added to the results object, no one really gets around to trimming unused data out of extendedInfo, but fair enough :P
| }); | ||
|
|
||
| const latency3gMin = Emulation.settings.TYPICAL_MOBILE_THROTTLING_METRICS.latency - 10; | ||
| const areLatenciesAll3G = allRequestLatencies.every(val => val > latency3gMin); |
There was a problem hiding this comment.
if you don't include areLatenciesAll3G in the extendedInfo, maybe pull this all into a areLatenciesAll3G(networkRecords) function?
There was a problem hiding this comment.
incidentally, this is a really cool way of checking that it's a sufficiently slow connection :)
|
PTAL. updated. |
|
@ebidel @brendankenny can i get an amen? |
| @@ -0,0 +1,62 @@ | |||
| /** | |||
| * @license Copyright 2017 Google Inc. All Rights Reserved. | |||
There was a problem hiding this comment.
i am very happy to change the codebase in one full sweep.
sounds perfect for another PR :P
| */ | ||
|
|
||
| const Audit = require('./audit'); | ||
| const TTIMetric = require('./time-to-interactive'); |
There was a problem hiding this comment.
calling into another audit really is an architecture smell, but we can fix that in a follow up
| static audit(artifacts) { | ||
| const networkRecords = artifacts.networkRecords[Audit.DEFAULT_PASS]; | ||
| const allRequestLatencies = networkRecords.map(record => { | ||
| if (!record._timing) return Infinity; |
There was a problem hiding this comment.
definitely don't want to depend on implicit NaN behavior. I was just wondering, but filtering does sound like it might be clearer (plus Infinity doesn't make it through JSON.stringify(), so it makes sense if including the latencies in the extendedInfo)
| TTIAudit.audit = generateTTIResults(5000); | ||
| return FastPWAAudit.audit(generateArtifacts()).then(result => { | ||
| assert.equal(result.rawValue, true, 'fixture trace is not passing audit'); | ||
| }).catch(err => { |
There was a problem hiding this comment.
don't need catch block (here and below), test will fail if a rejected promise is returned
|
|
||
| const extendedInfo = { | ||
| formatter: Formatter.SUPPORTED_FORMATS.NULL, | ||
| value: {allRequestLatencies, timeToInteractive} |
There was a problem hiding this comment.
i am just thinking that people will probably want to debug failures here ( in case throttling messed up or they are trying to use diff throttling or real cellular )...
and if we know that A BUNCH of their reqs were slow enough but 1 had a latency that barely missed things, then we can change our policy here.
OTOH things only get added to the results object, no one really gets around to trimming unused data out of extendedInfo, but fair enough :P


Basic audit that just checks TTI value against a threshold.
Current UI is

Note: I have this audit included in default.json here, but I will remove it before landing this PR. It's just there to make testing a bit easier. :)
Once landed, I will move the other perf metrics from PWA to Perf, leaving only this one in PWA.
Fixes #1831