lighthouse 8.0.0-dev.20210709 → 8.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/docs/architecture.md +101 -0
- package/docs/authenticated-pages.md +44 -0
- package/docs/bug-labels.md +35 -0
- package/docs/configuration.md +213 -0
- package/docs/emulation.md +32 -0
- package/docs/error-reporting.md +42 -0
- package/docs/hacking-tips.md +55 -0
- package/docs/headless-chrome.md +119 -0
- package/docs/lantern.md +55 -0
- package/docs/new-audits.md +99 -0
- package/docs/performance-budgets.md +187 -0
- package/docs/plugins.md +374 -0
- package/docs/puppeteer.md +95 -0
- package/docs/readme.md +164 -0
- package/docs/recipes/auth/README.md +129 -0
- package/docs/recipes/auth/example-lh-auth.js +81 -0
- package/docs/recipes/auth/package.json +11 -0
- package/docs/recipes/auth/server/public/dashboard-unauthenticated.html +21 -0
- package/docs/recipes/auth/server/public/dashboard.html +25 -0
- package/docs/recipes/auth/server/public/home-unauthenticated.html +27 -0
- package/docs/recipes/auth/server/public/home.html +17 -0
- package/docs/recipes/auth/server/public/unauthenticated.html +22 -0
- package/docs/recipes/auth/server/server.js +85 -0
- package/docs/recipes/custom-audit/custom-config.js +36 -0
- package/docs/recipes/custom-audit/package.json +8 -0
- package/docs/recipes/custom-audit/readme.md +32 -0
- package/docs/recipes/custom-audit/searchable-audit.js +46 -0
- package/docs/recipes/custom-audit/searchable-gatherer.js +32 -0
- package/docs/recipes/custom-gatherer-puppeteer/custom-audit.js +34 -0
- package/{root.js → docs/recipes/custom-gatherer-puppeteer/custom-config.js} +23 -2
- package/docs/recipes/custom-gatherer-puppeteer/custom-gatherer.js +51 -0
- package/docs/recipes/custom-gatherer-puppeteer/package.json +13 -0
- package/docs/recipes/custom-gatherer-puppeteer/readme.md +7 -0
- package/docs/recipes/custom-gatherer-puppeteer/test.sh +9 -0
- package/docs/recipes/gulp/gulpfile.js +79 -0
- package/docs/recipes/gulp/package.json +12 -0
- package/docs/recipes/gulp/public/index.html +22 -0
- package/docs/recipes/gulp/readme.md +6 -0
- package/docs/recipes/integration-test/README.md +14 -0
- package/docs/recipes/integration-test/example-lh-auth.test.js +160 -0
- package/docs/recipes/integration-test/package.json +9 -0
- package/docs/recipes/lighthouse-plugin-example/audits/preload-as.js +46 -0
- package/docs/recipes/lighthouse-plugin-example/package.json +11 -0
- package/docs/recipes/lighthouse-plugin-example/plugin-recipe-screenshot.png +0 -0
- package/docs/recipes/lighthouse-plugin-example/plugin.js +24 -0
- package/docs/recipes/lighthouse-plugin-example/readme.md +53 -0
- package/docs/releasing.md +164 -0
- package/docs/scoring.md +79 -0
- package/docs/throttling.md +150 -0
- package/docs/understanding-results.md +209 -0
- package/docs/v8-perf-faq.md +244 -0
- package/docs/variability.md +150 -0
- package/jest.config.js +0 -3
- package/lighthouse-cli/bin.js +8 -6
- package/lighthouse-core/audits/accessibility/aria-command-name.js +1 -1
- package/lighthouse-core/audits/accessibility/aria-meter-name.js +1 -1
- package/lighthouse-core/audits/accessibility/aria-progressbar-name.js +1 -1
- package/lighthouse-core/audits/accessibility/aria-tooltip-name.js +1 -1
- package/lighthouse-core/audits/accessibility/aria-treeitem-name.js +1 -1
- package/lighthouse-core/audits/apple-touch-icon.js +0 -1
- package/lighthouse-core/audits/audit.js +3 -3
- package/lighthouse-core/audits/autocomplete.js +2 -2
- package/lighthouse-core/audits/byte-efficiency/byte-efficiency-audit.js +14 -29
- package/lighthouse-core/audits/byte-efficiency/duplicated-javascript.js +2 -3
- package/lighthouse-core/audits/byte-efficiency/efficient-animated-content.js +1 -1
- package/lighthouse-core/audits/byte-efficiency/legacy-javascript.js +2 -3
- package/lighthouse-core/audits/byte-efficiency/modern-image-formats.js +15 -55
- package/lighthouse-core/audits/byte-efficiency/offscreen-images.js +4 -8
- package/lighthouse-core/audits/byte-efficiency/render-blocking-resources.js +8 -15
- package/lighthouse-core/audits/byte-efficiency/total-byte-weight.js +9 -10
- package/lighthouse-core/audits/byte-efficiency/unminified-css.js +1 -1
- package/lighthouse-core/audits/byte-efficiency/unminified-javascript.js +1 -1
- package/lighthouse-core/audits/byte-efficiency/unused-css-rules.js +1 -1
- package/lighthouse-core/audits/byte-efficiency/unused-javascript.js +1 -2
- package/lighthouse-core/audits/byte-efficiency/uses-long-cache-ttl.js +2 -2
- package/lighthouse-core/audits/byte-efficiency/uses-optimized-images.js +1 -2
- package/lighthouse-core/audits/byte-efficiency/uses-responsive-images.js +24 -46
- package/lighthouse-core/audits/byte-efficiency/uses-text-compression.js +1 -1
- package/lighthouse-core/audits/critical-request-chains.js +0 -1
- package/lighthouse-core/audits/csp-xss.js +1 -1
- package/lighthouse-core/audits/diagnostics.js +0 -1
- package/lighthouse-core/audits/dobetterweb/geolocation-on-start.js +0 -1
- package/lighthouse-core/audits/dobetterweb/inspector-issues.js +1 -1
- package/lighthouse-core/audits/dobetterweb/notification-on-start.js +0 -1
- package/lighthouse-core/audits/dobetterweb/uses-http2.js +0 -1
- package/lighthouse-core/audits/final-screenshot.js +4 -8
- package/lighthouse-core/audits/font-display.js +0 -1
- package/lighthouse-core/audits/installable-manifest.js +3 -4
- package/lighthouse-core/audits/largest-contentful-paint-element.js +0 -1
- package/lighthouse-core/audits/long-tasks.js +1 -1
- package/lighthouse-core/audits/maskable-icon.js +0 -1
- package/lighthouse-core/audits/metrics/first-contentful-paint-3g.js +2 -4
- package/lighthouse-core/audits/metrics/first-contentful-paint.js +2 -4
- package/lighthouse-core/audits/metrics/first-meaningful-paint.js +2 -4
- package/lighthouse-core/audits/metrics/interactive.js +2 -4
- package/lighthouse-core/audits/metrics/largest-contentful-paint.js +2 -4
- package/lighthouse-core/audits/metrics/max-potential-fid.js +2 -4
- package/lighthouse-core/audits/metrics/speed-index.js +2 -4
- package/lighthouse-core/audits/metrics/total-blocking-time.js +2 -10
- package/lighthouse-core/audits/metrics.js +2 -4
- package/lighthouse-core/audits/performance-budget.js +0 -1
- package/lighthouse-core/audits/predictive-perf.js +6 -9
- package/lighthouse-core/audits/preload-fonts.js +1 -11
- package/lighthouse-core/audits/preload-lcp-image.js +5 -18
- package/lighthouse-core/audits/redirects.js +8 -10
- package/lighthouse-core/audits/screenshot-thumbnails.js +13 -28
- package/lighthouse-core/audits/seo/canonical.js +1 -2
- package/lighthouse-core/audits/seo/font-size.js +4 -4
- package/lighthouse-core/audits/seo/hreflang.js +2 -3
- package/lighthouse-core/audits/seo/http-status-code.js +16 -21
- package/lighthouse-core/audits/seo/is-crawlable.js +3 -4
- package/lighthouse-core/audits/seo/robots-txt.js +2 -2
- package/lighthouse-core/audits/seo/tap-targets.js +5 -5
- package/lighthouse-core/audits/server-response-time.js +2 -20
- package/lighthouse-core/audits/splash-screen.js +0 -1
- package/lighthouse-core/audits/themed-omnibox.js +0 -1
- package/lighthouse-core/audits/third-party-facades.js +0 -1
- package/lighthouse-core/audits/third-party-summary.js +3 -1
- package/lighthouse-core/audits/timing-budget.js +2 -4
- package/lighthouse-core/audits/uses-rel-preconnect.js +9 -14
- package/lighthouse-core/audits/uses-rel-preload.js +2 -13
- package/lighthouse-core/computed/main-thread-tasks.js +2 -2
- package/lighthouse-core/computed/metrics/cumulative-layout-shift.js +3 -3
- package/lighthouse-core/computed/metrics/first-contentful-paint-all-frames.js +6 -6
- package/lighthouse-core/computed/metrics/first-contentful-paint.js +8 -9
- package/lighthouse-core/computed/metrics/first-meaningful-paint.js +9 -10
- package/lighthouse-core/computed/metrics/interactive.js +24 -25
- package/lighthouse-core/computed/metrics/lantern-first-contentful-paint.js +6 -6
- package/lighthouse-core/computed/metrics/lantern-first-meaningful-paint.js +6 -6
- package/lighthouse-core/computed/metrics/lantern-largest-contentful-paint.js +6 -6
- package/lighthouse-core/computed/metrics/lantern-metric.js +8 -16
- package/lighthouse-core/computed/metrics/largest-contentful-paint-all-frames.js +7 -7
- package/lighthouse-core/computed/metrics/largest-contentful-paint.js +9 -10
- package/lighthouse-core/computed/metrics/max-potential-fid.js +11 -8
- package/lighthouse-core/computed/metrics/metric.js +5 -32
- package/lighthouse-core/computed/metrics/speed-index.js +5 -6
- package/lighthouse-core/computed/metrics/timing-summary.js +45 -55
- package/lighthouse-core/computed/metrics/total-blocking-time.js +29 -36
- package/lighthouse-core/computed/page-dependency-graph.js +14 -14
- package/lighthouse-core/computed/resource-summary.js +7 -3
- package/lighthouse-core/computed/speedline.js +3 -3
- package/lighthouse-core/computed/trace-of-tab.js +86 -15
- package/lighthouse-core/computed/user-timings.js +5 -5
- package/lighthouse-core/config/default-config.js +0 -1
- package/lighthouse-core/fraggle-rock/config/config.js +7 -9
- package/lighthouse-core/fraggle-rock/config/default-config.js +2 -40
- package/lighthouse-core/fraggle-rock/config/filters.js +6 -39
- package/lighthouse-core/fraggle-rock/config/validation.js +4 -4
- package/lighthouse-core/fraggle-rock/gather/base-artifacts.js +19 -54
- package/lighthouse-core/fraggle-rock/gather/navigation-runner.js +10 -21
- package/lighthouse-core/fraggle-rock/gather/runner-helpers.js +2 -2
- package/lighthouse-core/fraggle-rock/gather/snapshot-runner.js +2 -2
- package/lighthouse-core/fraggle-rock/gather/timespan-runner.js +2 -2
- package/lighthouse-core/gather/driver/prepare.js +0 -3
- package/lighthouse-core/gather/fetcher.js +2 -0
- package/lighthouse-core/gather/gather-runner.js +14 -2
- package/lighthouse-core/gather/gatherers/image-elements.js +61 -24
- package/lighthouse-core/gather/gatherers/inspector-issues.js +2 -2
- package/lighthouse-core/gather/gatherers/script-elements.js +12 -45
- package/lighthouse-core/gather/gatherers/seo/font-size.js +5 -5
- package/lighthouse-core/gather/gatherers/seo/tap-targets.js +12 -64
- package/lighthouse-core/gather/gatherers/service-worker.js +3 -20
- package/lighthouse-core/gather/gatherers/trace-compat.js +1 -1
- package/lighthouse-core/gather/gatherers/trace-elements.js +3 -15
- package/lighthouse-core/gather/gatherers/trace.js +4 -13
- package/lighthouse-core/gather/gatherers/viewport-dimensions.js +1 -1
- package/lighthouse-core/lib/dependency-graph/simulator/network-analyzer.js +2 -13
- package/lighthouse-core/lib/emulation.js +2 -0
- package/lighthouse-core/lib/i18n/i18n.js +2 -2
- package/lighthouse-core/lib/i18n/locales/ar-XB.json +141 -141
- package/lighthouse-core/lib/i18n/locales/ar.json +143 -143
- package/lighthouse-core/lib/i18n/locales/bg.json +143 -143
- package/lighthouse-core/lib/i18n/locales/ca.json +141 -141
- package/lighthouse-core/lib/i18n/locales/cs.json +141 -141
- package/lighthouse-core/lib/i18n/locales/da.json +141 -141
- package/lighthouse-core/lib/i18n/locales/de.json +142 -142
- package/lighthouse-core/lib/i18n/locales/el.json +141 -141
- package/lighthouse-core/lib/i18n/locales/en-GB.json +141 -141
- package/lighthouse-core/lib/i18n/locales/en-US.ctc.json +6659 -0
- package/lighthouse-core/lib/i18n/locales/en-US.json +144 -150
- package/lighthouse-core/lib/i18n/locales/en-XA.json +141 -141
- package/lighthouse-core/lib/i18n/locales/en-XL.ctc.json +6628 -0
- package/lighthouse-core/lib/i18n/locales/en-XL.json +144 -150
- package/lighthouse-core/lib/i18n/locales/es-419.json +141 -141
- package/lighthouse-core/lib/i18n/locales/es.json +141 -141
- package/lighthouse-core/lib/i18n/locales/fi.json +143 -143
- package/lighthouse-core/lib/i18n/locales/fil.json +142 -142
- package/lighthouse-core/lib/i18n/locales/fr.json +141 -141
- package/lighthouse-core/lib/i18n/locales/he.json +142 -142
- package/lighthouse-core/lib/i18n/locales/hi.json +143 -143
- package/lighthouse-core/lib/i18n/locales/hr.json +141 -141
- package/lighthouse-core/lib/i18n/locales/hu.json +143 -143
- package/lighthouse-core/lib/i18n/locales/id.json +143 -143
- package/lighthouse-core/lib/i18n/locales/it.json +143 -143
- package/lighthouse-core/lib/i18n/locales/ja.json +143 -143
- package/lighthouse-core/lib/i18n/locales/ko.json +143 -143
- package/lighthouse-core/lib/i18n/locales/lt.json +143 -143
- package/lighthouse-core/lib/i18n/locales/lv.json +143 -143
- package/lighthouse-core/lib/i18n/locales/nl.json +141 -141
- package/lighthouse-core/lib/i18n/locales/no.json +141 -141
- package/lighthouse-core/lib/i18n/locales/pl.json +141 -141
- package/lighthouse-core/lib/i18n/locales/pt-PT.json +141 -141
- package/lighthouse-core/lib/i18n/locales/pt.json +141 -141
- package/lighthouse-core/lib/i18n/locales/ro.json +144 -144
- package/lighthouse-core/lib/i18n/locales/ru.json +143 -143
- package/lighthouse-core/lib/i18n/locales/sk.json +142 -142
- package/lighthouse-core/lib/i18n/locales/sl.json +141 -141
- package/lighthouse-core/lib/i18n/locales/sr-Latn.json +143 -143
- package/lighthouse-core/lib/i18n/locales/sr.json +143 -143
- package/lighthouse-core/lib/i18n/locales/sv.json +142 -142
- package/lighthouse-core/lib/i18n/locales/ta.json +141 -141
- package/lighthouse-core/lib/i18n/locales/te.json +143 -143
- package/lighthouse-core/lib/i18n/locales/th.json +143 -143
- package/lighthouse-core/lib/i18n/locales/tr.json +143 -143
- package/lighthouse-core/lib/i18n/locales/uk.json +141 -141
- package/lighthouse-core/lib/i18n/locales/vi.json +143 -143
- package/lighthouse-core/lib/i18n/locales/zh-HK.json +141 -141
- package/lighthouse-core/lib/i18n/locales/zh-TW.json +143 -143
- package/lighthouse-core/lib/i18n/locales/zh.json +143 -143
- package/lighthouse-core/lib/lh-error.js +2 -2
- package/lighthouse-core/lib/minify-trace.js +1 -1
- package/lighthouse-core/lib/network-request.js +1 -17
- package/lighthouse-core/lib/page-functions.js +5 -6
- package/lighthouse-core/lib/rect-helpers.js +3 -3
- package/lighthouse-core/lib/sd-validation/assets/jsonldcontext.json +7137 -0
- package/lighthouse-core/lib/sd-validation/assets/schema-tree.json +9900 -0
- package/{report/report-assets.js → lighthouse-core/lib/sd-validation/helpers/walk-object.js} +20 -12
- package/lighthouse-core/lib/sd-validation/json-expander.js +56 -0
- package/lighthouse-core/lib/sd-validation/json-linter.js +49 -0
- package/lighthouse-core/lib/sd-validation/jsonld-keyword-validator.js +50 -0
- package/lighthouse-core/lib/sd-validation/line-number-from-jsonld-path.js +60 -0
- package/lighthouse-core/lib/sd-validation/schema-validator.js +146 -0
- package/lighthouse-core/lib/sd-validation/scripts/download-jsonldcontext.js +30 -0
- package/lighthouse-core/lib/sd-validation/scripts/generate-schema-tree.js +97 -0
- package/lighthouse-core/lib/sd-validation/sd-validation.js +77 -0
- package/lighthouse-core/lib/tappable-rects.js +1 -1
- package/lighthouse-core/lib/tracehouse/trace-processor.js +42 -116
- package/lighthouse-core/lib/url-shim.js +2 -29
- package/lighthouse-core/report/html/html-report-assets.js +38 -0
- package/{report/README.md → lighthouse-core/report/html/readme.md} +11 -7
- package/{report → lighthouse-core/report/html}/renderer/category-renderer.js +0 -0
- package/{report → lighthouse-core/report/html}/renderer/crc-details-renderer.js +0 -0
- package/{report → lighthouse-core/report/html}/renderer/details-renderer.js +1 -1
- package/{report → lighthouse-core/report/html}/renderer/dom.js +0 -0
- package/{report → lighthouse-core/report/html}/renderer/element-screenshot-renderer.js +0 -0
- package/{report → lighthouse-core/report/html}/renderer/i18n.js +1 -1
- package/{report → lighthouse-core/report/html}/renderer/logger.js +0 -0
- package/{report → lighthouse-core/report/html}/renderer/performance-category-renderer.js +0 -0
- package/{report → lighthouse-core/report/html}/renderer/psi.js +0 -0
- package/{report → lighthouse-core/report/html}/renderer/pwa-category-renderer.js +0 -0
- package/{report → lighthouse-core/report/html}/renderer/report-renderer.js +0 -0
- package/{report → lighthouse-core/report/html}/renderer/report-ui-features.js +3 -3
- package/{report → lighthouse-core/report/html}/renderer/snippet-renderer.js +0 -0
- package/{report → lighthouse-core/report/html}/renderer/text-encoding.js +0 -0
- package/{report → lighthouse-core/report/html}/renderer/util.js +4 -7
- package/{report/assets/styles.css → lighthouse-core/report/html/report-styles.css} +0 -0
- package/{report/assets/standalone-template.html → lighthouse-core/report/html/report-template.html} +41 -1
- package/{report/assets → lighthouse-core/report/html}/templates.html +0 -0
- package/{report → lighthouse-core/report}/report-generator.js +1 -1
- package/lighthouse-core/runner.js +1 -1
- package/package.json +12 -13
- package/readme.md +2 -2
- package/third-party/chromium-synchronization/inspector-issueAdded-types-test.js +2 -3
- package/third-party/chromium-synchronization/installability-errors-test.js +2 -2
- package/third-party/download-content-shell/download-content-shell.js +1 -2
- package/third-party/snyk/snapshot.json +1 -1
- package/tsconfig.json +1 -0
- package/types/artifacts.d.ts +21 -41
- package/types/audit.d.ts +0 -2
- package/types/config.d.ts +2 -16
- package/types/externs.d.ts +0 -1
- package/types/gatherer.d.ts +13 -13
- package/types/html-renderer.d.ts +14 -14
- package/types/i18n.d.ts +1 -1
- package/lighthouse-core/audits/byte-efficiency/uses-responsive-images-snapshot.js +0 -94
- package/lighthouse-core/computed/image-records.js +0 -62
- package/lighthouse-core/computed/metrics/navigation-metric.js +0 -46
- package/lighthouse-core/computed/processed-navigation.js +0 -21
- package/lighthouse-core/computed/processed-trace.js +0 -21
- package/lighthouse-core/gather/gatherers/gather-context.js +0 -25
- package/lighthouse-core/gather/gatherers/host-form-factor.js +0 -31
- package/lighthouse-core/gather/gatherers/host-user-agent.js +0 -29
- package/lighthouse-core/lib/lh-trace-processor.js +0 -46
- package/report/clients/standalone.js +0 -52
- package/report/test/renderer/category-renderer-test.js +0 -488
- package/report/test/renderer/crc-details-renderer-test.js +0 -115
- package/report/test/renderer/details-renderer-test.js +0 -843
- package/report/test/renderer/dom-test.js +0 -157
- package/report/test/renderer/element-screenshot-renderer-test.js +0 -189
- package/report/test/renderer/i18n-test.js +0 -146
- package/report/test/renderer/performance-category-renderer-test.js +0 -332
- package/report/test/renderer/psi-test.js +0 -152
- package/report/test/renderer/pwa-category-renderer-test.js +0 -303
- package/report/test/renderer/report-renderer-test.js +0 -325
- package/report/test/renderer/report-ui-features-test.js +0 -572
- package/report/test/renderer/snippet-renderer-test.js +0 -291
- package/report/test/renderer/text-encoding-test.js +0 -41
- package/report/test/renderer/util-test.js +0 -388
- package/report/test/report-generator-test.js +0 -145
|
@@ -7,7 +7,8 @@
|
|
|
7
7
|
|
|
8
8
|
const makeComputedArtifact = require('../computed-artifact.js');
|
|
9
9
|
const ComputedMetric = require('./metric.js');
|
|
10
|
-
const
|
|
10
|
+
const LHError = require('../../lib/lh-error.js');
|
|
11
|
+
const TracingProcessor = require('../../lib/tracehouse/trace-processor.js');
|
|
11
12
|
const LanternTotalBlockingTime = require('./lantern-total-blocking-time.js');
|
|
12
13
|
const TimetoInteractive = require('./interactive.js');
|
|
13
14
|
|
|
@@ -31,15 +32,14 @@ class TotalBlockingTime extends ComputedMetric {
|
|
|
31
32
|
static get BLOCKING_TIME_THRESHOLD() {
|
|
32
33
|
return 50;
|
|
33
34
|
}
|
|
34
|
-
|
|
35
35
|
/**
|
|
36
36
|
* @param {Array<{start: number, end: number, duration: number}>} topLevelEvents
|
|
37
|
-
* @param {number}
|
|
38
|
-
* @param {number}
|
|
37
|
+
* @param {number} fcpTimeInMs
|
|
38
|
+
* @param {number} interactiveTimeMs
|
|
39
39
|
* @return {number}
|
|
40
40
|
*/
|
|
41
|
-
static calculateSumOfBlockingTime(topLevelEvents,
|
|
42
|
-
if (
|
|
41
|
+
static calculateSumOfBlockingTime(topLevelEvents, fcpTimeInMs, interactiveTimeMs) {
|
|
42
|
+
if (interactiveTimeMs <= fcpTimeInMs) return 0;
|
|
43
43
|
|
|
44
44
|
const threshold = TotalBlockingTime.BLOCKING_TIME_THRESHOLD;
|
|
45
45
|
let sumBlockingTime = 0;
|
|
@@ -47,22 +47,23 @@ class TotalBlockingTime extends ComputedMetric {
|
|
|
47
47
|
// Early exit for small tasks, which should far outnumber long tasks.
|
|
48
48
|
if (event.duration < threshold) continue;
|
|
49
49
|
|
|
50
|
-
// We only want to consider tasks that fall
|
|
50
|
+
// We only want to consider tasks that fall between FCP and TTI.
|
|
51
51
|
// FCP is picked as the lower bound because there is little risk of user input happening
|
|
52
52
|
// before FCP so Long Queuing Qelay regions do not harm user experience. Developers should be
|
|
53
53
|
// optimizing to reach FCP as fast as possible without having to worry about task lengths.
|
|
54
|
-
if (event.end <
|
|
54
|
+
if (event.end < fcpTimeInMs) continue;
|
|
55
55
|
|
|
56
|
-
// TTI is picked as the upper bound because we want a well defined end point
|
|
57
|
-
|
|
56
|
+
// TTI is picked as the upper bound because we want a well defined end point so that the
|
|
57
|
+
// metric does not rely on how long we trace.
|
|
58
|
+
if (event.start > interactiveTimeMs) continue;
|
|
58
59
|
|
|
59
60
|
// We first perform the clipping, and then calculate Blocking Region. So if we have a 150ms
|
|
60
61
|
// task [0, 150] and FCP happens midway at 50ms, we first clip the task to [50, 150], and then
|
|
61
62
|
// calculate the Blocking Region to be [100, 150]. The rational here is that tasks before FCP
|
|
62
63
|
// are unimportant, so we care whether the main thread is busy more than 50ms at a time only
|
|
63
64
|
// after FCP.
|
|
64
|
-
const clippedStart = Math.max(event.start,
|
|
65
|
-
const clippedEnd = Math.min(event.end,
|
|
65
|
+
const clippedStart = Math.max(event.start, fcpTimeInMs);
|
|
66
|
+
const clippedEnd = Math.min(event.end, interactiveTimeMs);
|
|
66
67
|
const clippedDuration = clippedEnd - clippedStart;
|
|
67
68
|
if (clippedDuration < threshold) continue;
|
|
68
69
|
|
|
@@ -70,7 +71,7 @@ class TotalBlockingTime extends ComputedMetric {
|
|
|
70
71
|
// Example:
|
|
71
72
|
// [ 250ms Task ]
|
|
72
73
|
// | First 50ms | Blocking Region (200ms) |
|
|
73
|
-
sumBlockingTime += clippedDuration - threshold;
|
|
74
|
+
sumBlockingTime += (clippedDuration - threshold);
|
|
74
75
|
}
|
|
75
76
|
|
|
76
77
|
return sumBlockingTime;
|
|
@@ -82,8 +83,7 @@ class TotalBlockingTime extends ComputedMetric {
|
|
|
82
83
|
* @return {Promise<LH.Artifacts.LanternMetric>}
|
|
83
84
|
*/
|
|
84
85
|
static computeSimulatedMetric(data, context) {
|
|
85
|
-
|
|
86
|
-
return LanternTotalBlockingTime.request(metricData, context);
|
|
86
|
+
return LanternTotalBlockingTime.request(data, context);
|
|
87
87
|
}
|
|
88
88
|
|
|
89
89
|
/**
|
|
@@ -92,29 +92,22 @@ class TotalBlockingTime extends ComputedMetric {
|
|
|
92
92
|
* @return {Promise<LH.Artifacts.Metric>}
|
|
93
93
|
*/
|
|
94
94
|
static async computeObservedMetric(data, context) {
|
|
95
|
-
const
|
|
95
|
+
const {firstContentfulPaint} = data.traceOfTab.timings;
|
|
96
|
+
if (!firstContentfulPaint) {
|
|
97
|
+
throw new LHError(LHError.errors.NO_FCP);
|
|
98
|
+
}
|
|
96
99
|
|
|
97
|
-
|
|
98
|
-
const {firstContentfulPaint} = data.processedNavigation.timings;
|
|
99
|
-
const metricData = ComputedMetric.getMetricComputationInput(data);
|
|
100
|
-
const interactiveTimeMs = (await TimetoInteractive.request(metricData, context)).timing;
|
|
100
|
+
const interactiveTimeMs = (await TimetoInteractive.request(data, context)).timing;
|
|
101
101
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
timing: TotalBlockingTime.calculateSumOfBlockingTime(
|
|
112
|
-
events,
|
|
113
|
-
0,
|
|
114
|
-
data.processedTrace.timestamps.traceEnd
|
|
115
|
-
),
|
|
116
|
-
};
|
|
117
|
-
}
|
|
102
|
+
const events = TracingProcessor.getMainThreadTopLevelEvents(data.traceOfTab);
|
|
103
|
+
|
|
104
|
+
return {
|
|
105
|
+
timing: TotalBlockingTime.calculateSumOfBlockingTime(
|
|
106
|
+
events,
|
|
107
|
+
firstContentfulPaint,
|
|
108
|
+
interactiveTimeMs
|
|
109
|
+
),
|
|
110
|
+
};
|
|
118
111
|
}
|
|
119
112
|
}
|
|
120
113
|
|
|
@@ -11,7 +11,7 @@ const CPUNode = require('../lib/dependency-graph/cpu-node.js');
|
|
|
11
11
|
const NetworkAnalyzer = require('../lib/dependency-graph/simulator/network-analyzer.js');
|
|
12
12
|
const TracingProcessor = require('../lib/tracehouse/trace-processor.js');
|
|
13
13
|
const NetworkRequest = require('../lib/network-request.js');
|
|
14
|
-
const
|
|
14
|
+
const TraceOfTab = require('./trace-of-tab.js');
|
|
15
15
|
const NetworkRecords = require('./network-records.js');
|
|
16
16
|
|
|
17
17
|
/** @typedef {import('../lib/dependency-graph/base-node.js').Node} Node */
|
|
@@ -102,18 +102,18 @@ class PageDependencyGraph {
|
|
|
102
102
|
}
|
|
103
103
|
|
|
104
104
|
/**
|
|
105
|
-
* @param {LH.Artifacts.
|
|
105
|
+
* @param {LH.Artifacts.TraceOfTab} traceOfTab
|
|
106
106
|
* @return {Array<CPUNode>}
|
|
107
107
|
*/
|
|
108
|
-
static getCPUNodes(
|
|
108
|
+
static getCPUNodes(traceOfTab) {
|
|
109
109
|
/** @type {Array<CPUNode>} */
|
|
110
110
|
const nodes = [];
|
|
111
111
|
let i = 0;
|
|
112
112
|
|
|
113
|
-
TracingProcessor.assertHasToplevelEvents(mainThreadEvents);
|
|
113
|
+
TracingProcessor.assertHasToplevelEvents(traceOfTab.mainThreadEvents);
|
|
114
114
|
|
|
115
|
-
while (i < mainThreadEvents.length) {
|
|
116
|
-
const evt = mainThreadEvents[i];
|
|
115
|
+
while (i < traceOfTab.mainThreadEvents.length) {
|
|
116
|
+
const evt = traceOfTab.mainThreadEvents[i];
|
|
117
117
|
i++;
|
|
118
118
|
|
|
119
119
|
// Skip all trace events that aren't schedulable tasks with sizable duration
|
|
@@ -126,10 +126,10 @@ class PageDependencyGraph {
|
|
|
126
126
|
const children = [];
|
|
127
127
|
for (
|
|
128
128
|
const endTime = evt.ts + evt.dur;
|
|
129
|
-
i < mainThreadEvents.length && mainThreadEvents[i].ts < endTime;
|
|
129
|
+
i < traceOfTab.mainThreadEvents.length && traceOfTab.mainThreadEvents[i].ts < endTime;
|
|
130
130
|
i++
|
|
131
131
|
) {
|
|
132
|
-
children.push(mainThreadEvents[i]);
|
|
132
|
+
children.push(traceOfTab.mainThreadEvents[i]);
|
|
133
133
|
}
|
|
134
134
|
|
|
135
135
|
nodes.push(new CPUNode(evt, children));
|
|
@@ -380,13 +380,13 @@ class PageDependencyGraph {
|
|
|
380
380
|
}
|
|
381
381
|
|
|
382
382
|
/**
|
|
383
|
-
* @param {LH.Artifacts.
|
|
383
|
+
* @param {LH.Artifacts.TraceOfTab} traceOfTab
|
|
384
384
|
* @param {Array<LH.Artifacts.NetworkRequest>} networkRecords
|
|
385
385
|
* @return {Node}
|
|
386
386
|
*/
|
|
387
|
-
static createGraph(
|
|
387
|
+
static createGraph(traceOfTab, networkRecords) {
|
|
388
388
|
const networkNodeOutput = PageDependencyGraph.getNetworkNodeOutput(networkRecords);
|
|
389
|
-
const cpuNodes = PageDependencyGraph.getCPUNodes(
|
|
389
|
+
const cpuNodes = PageDependencyGraph.getCPUNodes(traceOfTab);
|
|
390
390
|
|
|
391
391
|
// The root request is the earliest network request, using position in networkRecords array to break ties.
|
|
392
392
|
const rootRequest = networkRecords.reduce((min, r) => (r.startTime < min.startTime ? r : min));
|
|
@@ -458,12 +458,12 @@ class PageDependencyGraph {
|
|
|
458
458
|
static async compute_(data, context) {
|
|
459
459
|
const trace = data.trace;
|
|
460
460
|
const devtoolsLog = data.devtoolsLog;
|
|
461
|
-
const [
|
|
462
|
-
|
|
461
|
+
const [traceOfTab, networkRecords] = await Promise.all([
|
|
462
|
+
TraceOfTab.request(trace, context),
|
|
463
463
|
NetworkRecords.request(devtoolsLog, context),
|
|
464
464
|
]);
|
|
465
465
|
|
|
466
|
-
return PageDependencyGraph.createGraph(
|
|
466
|
+
return PageDependencyGraph.createGraph(traceOfTab, networkRecords);
|
|
467
467
|
}
|
|
468
468
|
}
|
|
469
469
|
|
|
@@ -9,8 +9,9 @@ const makeComputedArtifact = require('./computed-artifact.js');
|
|
|
9
9
|
const NetworkRecords = require('./network-records.js');
|
|
10
10
|
const URL = require('../lib/url-shim.js');
|
|
11
11
|
const NetworkRequest = require('../lib/network-request.js');
|
|
12
|
+
const MainResource = require('./main-resource.js');
|
|
12
13
|
const Budget = require('../config/budget.js');
|
|
13
|
-
const Util = require('
|
|
14
|
+
const Util = require('../report/html/renderer/util.js');
|
|
14
15
|
|
|
15
16
|
/** @typedef {{count: number, resourceSize: number, transferSize: number}} ResourceEntry */
|
|
16
17
|
|
|
@@ -106,8 +107,11 @@ class ResourceSummary {
|
|
|
106
107
|
* @return {Promise<Record<LH.Budget.ResourceType,ResourceEntry>>}
|
|
107
108
|
*/
|
|
108
109
|
static async compute_(data, context) {
|
|
109
|
-
const networkRecords = await
|
|
110
|
-
|
|
110
|
+
const [networkRecords, mainResource] = await Promise.all([
|
|
111
|
+
NetworkRecords.request(data.devtoolsLog, context),
|
|
112
|
+
MainResource.request({devtoolsLog: data.devtoolsLog, URL: data.URL}, context),
|
|
113
|
+
]);
|
|
114
|
+
return ResourceSummary.summarize(networkRecords, mainResource.url, data.budgets);
|
|
111
115
|
}
|
|
112
116
|
}
|
|
113
117
|
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
const makeComputedArtifact = require('./computed-artifact.js');
|
|
9
9
|
const speedline = require('speedline-core');
|
|
10
10
|
const LHError = require('../lib/lh-error.js');
|
|
11
|
-
const
|
|
11
|
+
const TraceOfTab = require('./trace-of-tab.js');
|
|
12
12
|
|
|
13
13
|
class Speedline {
|
|
14
14
|
/**
|
|
@@ -19,13 +19,13 @@ class Speedline {
|
|
|
19
19
|
static async compute_(trace, context) {
|
|
20
20
|
// speedline() may throw without a promise, so we resolve immediately
|
|
21
21
|
// to get in a promise chain.
|
|
22
|
-
return
|
|
22
|
+
return TraceOfTab.request(trace, context).then(traceOfTab => {
|
|
23
23
|
// Use a shallow copy of traceEvents so speedline can sort as it pleases.
|
|
24
24
|
// See https://github.com/GoogleChrome/lighthouse/issues/2333
|
|
25
25
|
const traceEvents = trace.traceEvents.slice();
|
|
26
26
|
// Force use of timeOrigin as reference point for speedline
|
|
27
27
|
// See https://github.com/GoogleChrome/lighthouse/issues/2095
|
|
28
|
-
const timeOrigin =
|
|
28
|
+
const timeOrigin = traceOfTab.timestamps.timeOrigin;
|
|
29
29
|
return speedline(traceEvents, {
|
|
30
30
|
timeOrigin,
|
|
31
31
|
fastMode: true,
|
|
@@ -5,26 +5,97 @@
|
|
|
5
5
|
*/
|
|
6
6
|
'use strict';
|
|
7
7
|
|
|
8
|
-
/** @fileoverview This file is no longer used internally, but remains here for backcompat with plugins. */
|
|
9
|
-
|
|
10
|
-
const log = require('lighthouse-logger');
|
|
11
8
|
const makeComputedArtifact = require('./computed-artifact.js');
|
|
12
|
-
const
|
|
13
|
-
const
|
|
9
|
+
const LHError = require('../lib/lh-error.js');
|
|
10
|
+
const TraceProcessor = require('../lib/tracehouse/trace-processor.js');
|
|
11
|
+
|
|
12
|
+
// TraceProcessor throws generic errors, but we'd like our special localized and code-specific LHError
|
|
13
|
+
// objects to be thrown instead.
|
|
14
|
+
class LHTraceProcessor extends TraceProcessor {
|
|
15
|
+
/**
|
|
16
|
+
* @return {Error}
|
|
17
|
+
*/
|
|
18
|
+
static createNoNavstartError() {
|
|
19
|
+
return new LHError(LHError.errors.NO_NAVSTART);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* This isn't currently used, but will be when the time origin of trace processing is changed.
|
|
24
|
+
* @see {TraceProcessor.computeTimeOrigin}
|
|
25
|
+
* @see https://github.com/GoogleChrome/lighthouse/pull/11253#discussion_r507985527
|
|
26
|
+
* @return {Error}
|
|
27
|
+
*/
|
|
28
|
+
static createNoResourceSendRequestError() {
|
|
29
|
+
return new LHError(LHError.errors.NO_RESOURCE_REQUEST);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* @return {Error}
|
|
34
|
+
*/
|
|
35
|
+
static createNoTracingStartedError() {
|
|
36
|
+
return new LHError(LHError.errors.NO_TRACING_STARTED);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
14
40
|
|
|
15
41
|
class TraceOfTab {
|
|
16
42
|
/**
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
43
|
+
* Finds key trace events, identifies main process/thread, and returns timings of trace events
|
|
44
|
+
* in milliseconds since navigation start in addition to the standard microsecond monotonic timestamps.
|
|
45
|
+
* @param {LH.Trace} trace
|
|
46
|
+
* @return {Promise<LH.Artifacts.TraceOfTab>}
|
|
47
|
+
*/
|
|
48
|
+
static async compute_(trace) {
|
|
49
|
+
// Trace of tab doesn't require FCP to exist, but all of LH requires it.
|
|
50
|
+
// We'll check that we got an FCP here and re-type accordingly so all of our consumers don't
|
|
51
|
+
// have to repeat this check.
|
|
52
|
+
const traceOfTab = await LHTraceProcessor.computeTraceOfTab(trace);
|
|
53
|
+
const {
|
|
54
|
+
timings,
|
|
55
|
+
timestamps,
|
|
56
|
+
firstContentfulPaintEvt,
|
|
57
|
+
firstContentfulPaintAllFramesEvt,
|
|
58
|
+
} = traceOfTab;
|
|
59
|
+
const {
|
|
60
|
+
firstContentfulPaint: firstContentfulPaintTiming,
|
|
61
|
+
firstContentfulPaintAllFrames: firstContentfulPaintAllFramesTiming,
|
|
62
|
+
} = timings;
|
|
63
|
+
const {
|
|
64
|
+
firstContentfulPaint: firstContentfulPaintTs,
|
|
65
|
+
firstContentfulPaintAllFrames: firstContentfulPaintAllFramesTs,
|
|
66
|
+
} = timestamps;
|
|
67
|
+
|
|
68
|
+
if (
|
|
69
|
+
!firstContentfulPaintEvt ||
|
|
70
|
+
firstContentfulPaintTiming === undefined ||
|
|
71
|
+
firstContentfulPaintTs === undefined ||
|
|
72
|
+
// FCP-AF will only be undefined if FCP is also undefined.
|
|
73
|
+
// These conditions are for enforcing types and should never actually trigger.
|
|
74
|
+
!firstContentfulPaintAllFramesEvt ||
|
|
75
|
+
firstContentfulPaintAllFramesTiming === undefined ||
|
|
76
|
+
firstContentfulPaintAllFramesTs === undefined
|
|
77
|
+
) {
|
|
78
|
+
throw new LHError(LHError.errors.NO_FCP);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// We already know that `traceOfTab` is good to go at this point, but tsc doesn't yet.
|
|
82
|
+
// Help tsc out by reconstructing the object manually with the known defined values.
|
|
83
|
+
return {
|
|
84
|
+
...traceOfTab,
|
|
85
|
+
firstContentfulPaintEvt,
|
|
86
|
+
firstContentfulPaintAllFramesEvt,
|
|
87
|
+
timings: {
|
|
88
|
+
...timings,
|
|
89
|
+
firstContentfulPaint: firstContentfulPaintTiming,
|
|
90
|
+
firstContentfulPaintAllFrames: firstContentfulPaintAllFramesTiming,
|
|
91
|
+
},
|
|
92
|
+
timestamps: {
|
|
93
|
+
...timestamps,
|
|
94
|
+
firstContentfulPaint: firstContentfulPaintTs,
|
|
95
|
+
firstContentfulPaintAllFrames: firstContentfulPaintAllFramesTs,
|
|
96
|
+
},
|
|
97
|
+
};
|
|
25
98
|
}
|
|
26
99
|
}
|
|
27
100
|
|
|
28
|
-
log.warn(`trace-of-tab`, `trace-of-tab is deprecated, use processed-trace / processed-navigation instead`); // eslint-disable-line max-len
|
|
29
101
|
module.exports = makeComputedArtifact(TraceOfTab);
|
|
30
|
-
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
'use strict';
|
|
7
7
|
|
|
8
8
|
const makeComputedArtifact = require('./computed-artifact.js');
|
|
9
|
-
const
|
|
9
|
+
const TraceOfTab = require('./trace-of-tab.js');
|
|
10
10
|
|
|
11
11
|
/** @typedef {{name: string, isMark: true, args: LH.TraceEvent['args'], startTime: number}} MarkEvent */
|
|
12
12
|
/** @typedef {{name: string, isMark: false, args: LH.TraceEvent['args'], startTime: number, endTime: number, duration: number}} MeasureEvent */
|
|
@@ -18,7 +18,7 @@ class UserTimings {
|
|
|
18
18
|
* @return {Promise<Array<MarkEvent|MeasureEvent>>}
|
|
19
19
|
*/
|
|
20
20
|
static async compute_(trace, context) {
|
|
21
|
-
const
|
|
21
|
+
const traceOfTab = await TraceOfTab.request(trace, context);
|
|
22
22
|
/** @type {Array<MarkEvent|MeasureEvent>} */
|
|
23
23
|
const userTimings = [];
|
|
24
24
|
/** @type {Record<string, number>} */
|
|
@@ -28,7 +28,7 @@ class UserTimings {
|
|
|
28
28
|
// The event phases we are interested in are mark and instant events (R, i, I)
|
|
29
29
|
// and duration events which correspond to measures (B, b, E, e).
|
|
30
30
|
// @see https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU/preview#
|
|
31
|
-
|
|
31
|
+
traceOfTab.processEvents.filter(evt => {
|
|
32
32
|
if (!evt.cat.includes('blink.user_timing')) {
|
|
33
33
|
return false;
|
|
34
34
|
}
|
|
@@ -69,9 +69,9 @@ class UserTimings {
|
|
|
69
69
|
|
|
70
70
|
// baseline the timestamps against the timeOrigin, and translate to milliseconds
|
|
71
71
|
userTimings.forEach(ut => {
|
|
72
|
-
ut.startTime = (ut.startTime -
|
|
72
|
+
ut.startTime = (ut.startTime - traceOfTab.timeOriginEvt.ts) / 1000;
|
|
73
73
|
if (!ut.isMark) {
|
|
74
|
-
ut.endTime = (ut.endTime -
|
|
74
|
+
ut.endTime = (ut.endTime - traceOfTab.timeOriginEvt.ts) / 1000;
|
|
75
75
|
ut.duration = ut.duration / 1000;
|
|
76
76
|
}
|
|
77
77
|
});
|
|
@@ -57,9 +57,9 @@ function resolveWorkingCopy(configJSON, context) {
|
|
|
57
57
|
* Looks up the required artifact IDs for each dependency, throwing if no earlier artifact satisfies the dependency.
|
|
58
58
|
*
|
|
59
59
|
* @param {LH.Config.ArtifactJson} artifact
|
|
60
|
-
* @param {LH.Config.
|
|
61
|
-
* @param {Map<Symbol, LH.Config.
|
|
62
|
-
* @return {LH.Config.
|
|
60
|
+
* @param {LH.Config.FRGathererDefn} gatherer
|
|
61
|
+
* @param {Map<Symbol, LH.Config.ArtifactDefn>} artifactDefnsBySymbol
|
|
62
|
+
* @return {LH.Config.ArtifactDefn['dependencies']}
|
|
63
63
|
*/
|
|
64
64
|
function resolveArtifactDependencies(artifact, gatherer, artifactDefnsBySymbol) {
|
|
65
65
|
if (!('dependencies' in gatherer.instance.meta)) return undefined;
|
|
@@ -86,7 +86,7 @@ function resolveArtifactDependencies(artifact, gatherer, artifactDefnsBySymbol)
|
|
|
86
86
|
*
|
|
87
87
|
* @param {LH.Config.ArtifactJson[]|null|undefined} artifacts
|
|
88
88
|
* @param {string|undefined} configDir
|
|
89
|
-
* @return {LH.Config.
|
|
89
|
+
* @return {LH.Config.ArtifactDefn[] | null}
|
|
90
90
|
*/
|
|
91
91
|
function resolveArtifactsToDefns(artifacts, configDir) {
|
|
92
92
|
if (!artifacts) return null;
|
|
@@ -94,7 +94,7 @@ function resolveArtifactsToDefns(artifacts, configDir) {
|
|
|
94
94
|
const status = {msg: 'Resolve artifact definitions', id: 'lh:config:resolveArtifactsToDefns'};
|
|
95
95
|
log.time(status, 'verbose');
|
|
96
96
|
|
|
97
|
-
/** @type {Map<Symbol, LH.Config.
|
|
97
|
+
/** @type {Map<Symbol, LH.Config.ArtifactDefn>} */
|
|
98
98
|
const artifactDefnsBySymbol = new Map();
|
|
99
99
|
|
|
100
100
|
const coreGathererList = Runner.getGathererList();
|
|
@@ -108,9 +108,7 @@ function resolveArtifactsToDefns(artifacts, configDir) {
|
|
|
108
108
|
throw new Error(`${gatherer.instance.name} gatherer does not support Fraggle Rock`);
|
|
109
109
|
}
|
|
110
110
|
|
|
111
|
-
/** @type {LH.Config.
|
|
112
|
-
// @ts-expect-error - Typescript can't validate the gatherer and dependencies match
|
|
113
|
-
// even though it knows that they're each valid on their own.
|
|
111
|
+
/** @type {LH.Config.ArtifactDefn<LH.Gatherer.DependencyKey>} */
|
|
114
112
|
const artifact = {
|
|
115
113
|
id: artifactJson.id,
|
|
116
114
|
gatherer,
|
|
@@ -129,7 +127,7 @@ function resolveArtifactsToDefns(artifacts, configDir) {
|
|
|
129
127
|
/**
|
|
130
128
|
*
|
|
131
129
|
* @param {LH.Config.NavigationJson[]|null|undefined} navigations
|
|
132
|
-
* @param {LH.Config.
|
|
130
|
+
* @param {LH.Config.ArtifactDefn[]|null|undefined} artifactDefns
|
|
133
131
|
* @return {LH.Config.NavigationDefn[] | null}
|
|
134
132
|
*/
|
|
135
133
|
function resolveNavigationsToDefns(navigations, artifactDefns) {
|
|
@@ -7,29 +7,6 @@
|
|
|
7
7
|
|
|
8
8
|
const legacyDefaultConfig = require('../../config/default-config.js');
|
|
9
9
|
|
|
10
|
-
/** @type {LH.Config.AuditJson[]} */
|
|
11
|
-
const frAudits = [
|
|
12
|
-
'byte-efficiency/uses-responsive-images-snapshot',
|
|
13
|
-
];
|
|
14
|
-
|
|
15
|
-
/** @type {Record<string, LH.Config.AuditRefJson[]>} */
|
|
16
|
-
const frCategoryAuditRefExtensions = {
|
|
17
|
-
'performance': [
|
|
18
|
-
{id: 'uses-responsive-images-snapshot', weight: 0, group: 'diagnostics'},
|
|
19
|
-
],
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
/** @return {LH.Config.Json['categories']} */
|
|
23
|
-
function mergeCategories() {
|
|
24
|
-
if (!legacyDefaultConfig.categories) return {};
|
|
25
|
-
const categories = legacyDefaultConfig.categories;
|
|
26
|
-
for (const key of Object.keys(frCategoryAuditRefExtensions)) {
|
|
27
|
-
if (!categories[key]) continue;
|
|
28
|
-
categories[key].auditRefs.push(...frCategoryAuditRefExtensions[key]);
|
|
29
|
-
}
|
|
30
|
-
return categories;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
10
|
// Ensure all artifact IDs match the typedefs.
|
|
34
11
|
/** @type {Record<keyof LH.FRArtifacts, string>} */
|
|
35
12
|
const artifacts = {
|
|
@@ -47,10 +24,7 @@ const artifacts = {
|
|
|
47
24
|
FontSize: '',
|
|
48
25
|
FormElements: '',
|
|
49
26
|
FullPageScreenshot: '',
|
|
50
|
-
GatherContext: '',
|
|
51
27
|
GlobalListeners: '',
|
|
52
|
-
HostFormFactor: '',
|
|
53
|
-
HostUserAgent: '',
|
|
54
28
|
IFrameElements: '',
|
|
55
29
|
ImageElements: '',
|
|
56
30
|
InstallabilityErrors: '',
|
|
@@ -64,8 +38,6 @@ const artifacts = {
|
|
|
64
38
|
PasswordInputsWithPreventedPaste: '',
|
|
65
39
|
ResponseCompression: '',
|
|
66
40
|
RobotsTxt: '',
|
|
67
|
-
ServiceWorker: '',
|
|
68
|
-
ScriptElements: '',
|
|
69
41
|
SourceMaps: '',
|
|
70
42
|
Stacks: '',
|
|
71
43
|
TagsBlockingFirstPaint: '',
|
|
@@ -85,8 +57,6 @@ for (const key of Object.keys(artifacts)) {
|
|
|
85
57
|
const defaultConfig = {
|
|
86
58
|
artifacts: [
|
|
87
59
|
// Artifacts which can be depended on come first.
|
|
88
|
-
{id: artifacts.HostUserAgent, gatherer: 'host-user-agent'},
|
|
89
|
-
{id: artifacts.HostFormFactor, gatherer: 'host-form-factor'},
|
|
90
60
|
{id: artifacts.DevtoolsLog, gatherer: 'devtools-log'},
|
|
91
61
|
{id: artifacts.Trace, gatherer: 'trace'},
|
|
92
62
|
|
|
@@ -103,7 +73,6 @@ const defaultConfig = {
|
|
|
103
73
|
{id: artifacts.FontSize, gatherer: 'seo/font-size'},
|
|
104
74
|
{id: artifacts.FormElements, gatherer: 'form-elements'},
|
|
105
75
|
{id: artifacts.FullPageScreenshot, gatherer: 'full-page-screenshot'},
|
|
106
|
-
{id: artifacts.GatherContext, gatherer: 'gather-context'},
|
|
107
76
|
{id: artifacts.GlobalListeners, gatherer: 'global-listeners'},
|
|
108
77
|
{id: artifacts.IFrameElements, gatherer: 'iframe-elements'},
|
|
109
78
|
{id: artifacts.ImageElements, gatherer: 'image-elements'},
|
|
@@ -118,8 +87,6 @@ const defaultConfig = {
|
|
|
118
87
|
{id: artifacts.PasswordInputsWithPreventedPaste, gatherer: 'dobetterweb/password-inputs-with-prevented-paste'},
|
|
119
88
|
{id: artifacts.ResponseCompression, gatherer: 'dobetterweb/response-compression'},
|
|
120
89
|
{id: artifacts.RobotsTxt, gatherer: 'seo/robots-txt'},
|
|
121
|
-
{id: artifacts.ServiceWorker, gatherer: 'service-worker'},
|
|
122
|
-
{id: artifacts.ScriptElements, gatherer: 'script-elements'},
|
|
123
90
|
{id: artifacts.SourceMaps, gatherer: 'source-maps'},
|
|
124
91
|
{id: artifacts.Stacks, gatherer: 'stacks'},
|
|
125
92
|
{id: artifacts.TagsBlockingFirstPaint, gatherer: 'dobetterweb/tags-blocking-first-paint'},
|
|
@@ -142,8 +109,6 @@ const defaultConfig = {
|
|
|
142
109
|
cpuQuietThresholdMs: 1000,
|
|
143
110
|
artifacts: [
|
|
144
111
|
// Artifacts which can be depended on come first.
|
|
145
|
-
artifacts.HostUserAgent,
|
|
146
|
-
artifacts.HostFormFactor,
|
|
147
112
|
artifacts.DevtoolsLog,
|
|
148
113
|
artifacts.Trace,
|
|
149
114
|
|
|
@@ -159,7 +124,6 @@ const defaultConfig = {
|
|
|
159
124
|
artifacts.FontSize,
|
|
160
125
|
artifacts.FormElements,
|
|
161
126
|
artifacts.FullPageScreenshot,
|
|
162
|
-
artifacts.GatherContext,
|
|
163
127
|
artifacts.GlobalListeners,
|
|
164
128
|
artifacts.IFrameElements,
|
|
165
129
|
artifacts.ImageElements,
|
|
@@ -174,8 +138,6 @@ const defaultConfig = {
|
|
|
174
138
|
artifacts.PasswordInputsWithPreventedPaste,
|
|
175
139
|
artifacts.ResponseCompression,
|
|
176
140
|
artifacts.RobotsTxt,
|
|
177
|
-
artifacts.ServiceWorker,
|
|
178
|
-
artifacts.ScriptElements,
|
|
179
141
|
artifacts.SourceMaps,
|
|
180
142
|
artifacts.Stacks,
|
|
181
143
|
artifacts.TagsBlockingFirstPaint,
|
|
@@ -191,8 +153,8 @@ const defaultConfig = {
|
|
|
191
153
|
},
|
|
192
154
|
],
|
|
193
155
|
settings: legacyDefaultConfig.settings,
|
|
194
|
-
audits:
|
|
195
|
-
categories:
|
|
156
|
+
audits: legacyDefaultConfig.audits,
|
|
157
|
+
categories: legacyDefaultConfig.categories,
|
|
196
158
|
groups: legacyDefaultConfig.groups,
|
|
197
159
|
};
|
|
198
160
|
|
|
@@ -7,19 +7,6 @@
|
|
|
7
7
|
|
|
8
8
|
const Audit = require('../../audits/audit.js');
|
|
9
9
|
|
|
10
|
-
/** @type {Record<keyof LH.FRBaseArtifacts, string>} */
|
|
11
|
-
const baseArtifactKeySource = {
|
|
12
|
-
fetchTime: '',
|
|
13
|
-
LighthouseRunWarnings: '',
|
|
14
|
-
BenchmarkIndex: '',
|
|
15
|
-
settings: '',
|
|
16
|
-
Timing: '',
|
|
17
|
-
URL: '',
|
|
18
|
-
PageLoadError: '',
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
const baseArtifactKeys = Object.keys(baseArtifactKeySource);
|
|
22
|
-
|
|
23
10
|
/**
|
|
24
11
|
* Filters an array of artifacts down to the set that supports the specified gather mode.
|
|
25
12
|
*
|
|
@@ -38,35 +25,17 @@ function filterArtifactsByGatherMode(artifacts, mode) {
|
|
|
38
25
|
* Filters an array of audits down to the set that can be computed using only the specified artifacts.
|
|
39
26
|
*
|
|
40
27
|
* @param {LH.Config.FRConfig['audits']} audits
|
|
41
|
-
* @param {Array<LH.Config.
|
|
28
|
+
* @param {Array<LH.Config.ArtifactDefn>} availableArtifacts
|
|
42
29
|
* @return {LH.Config.FRConfig['audits']}
|
|
43
30
|
*/
|
|
44
31
|
function filterAuditsByAvailableArtifacts(audits, availableArtifacts) {
|
|
45
32
|
if (!audits) return null;
|
|
46
33
|
|
|
47
|
-
const
|
|
48
|
-
availableArtifacts.map(artifact => artifact.id).concat(baseArtifactKeys)
|
|
49
|
-
);
|
|
50
|
-
return audits.filter(audit => {
|
|
51
|
-
const meta = audit.implementation.meta;
|
|
52
|
-
return meta.requiredArtifacts.every(id => availableArtifactIds.has(id));
|
|
53
|
-
});
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Optional `supportedModes` property can explicitly exclude an audit even if all required artifacts are available.
|
|
58
|
-
*
|
|
59
|
-
* @param {LH.Config.FRConfig['audits']} audits
|
|
60
|
-
* @param {LH.Gatherer.GatherMode} mode
|
|
61
|
-
* @return {LH.Config.FRConfig['audits']}
|
|
62
|
-
*/
|
|
63
|
-
function filterAuditsByGatherMode(audits, mode) {
|
|
64
|
-
if (!audits) return null;
|
|
34
|
+
const availableAritfactIds = new Set(availableArtifacts.map(artifact => artifact.id));
|
|
65
35
|
|
|
66
|
-
return audits.filter(audit =>
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
});
|
|
36
|
+
return audits.filter(audit =>
|
|
37
|
+
audit.implementation.meta.requiredArtifacts.every(id => availableAritfactIds.has(id))
|
|
38
|
+
);
|
|
70
39
|
}
|
|
71
40
|
|
|
72
41
|
/**
|
|
@@ -117,8 +86,7 @@ function filterCategoriesByAvailableAudits(categories, availableAudits) {
|
|
|
117
86
|
*/
|
|
118
87
|
function filterConfigByGatherMode(config, mode) {
|
|
119
88
|
const artifacts = filterArtifactsByGatherMode(config.artifacts, mode);
|
|
120
|
-
const
|
|
121
|
-
const audits = filterAuditsByGatherMode(availableAudits, mode);
|
|
89
|
+
const audits = filterAuditsByAvailableArtifacts(config.audits, artifacts || []);
|
|
122
90
|
const categories = filterCategoriesByAvailableAudits(config.categories, audits || []);
|
|
123
91
|
|
|
124
92
|
return {
|
|
@@ -133,6 +101,5 @@ module.exports = {
|
|
|
133
101
|
filterConfigByGatherMode,
|
|
134
102
|
filterArtifactsByGatherMode,
|
|
135
103
|
filterAuditsByAvailableArtifacts,
|
|
136
|
-
filterAuditsByGatherMode,
|
|
137
104
|
filterCategoriesByAvailableAudits,
|
|
138
105
|
};
|