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
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
'use strict';
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
|
-
* @param {LH.Config.GathererDefn | LH.Config.
|
|
10
|
-
* @return {gathererDefn is LH.Config.
|
|
9
|
+
* @param {LH.Config.GathererDefn | LH.Config.FRGathererDefn} gathererDefn
|
|
10
|
+
* @return {gathererDefn is LH.Config.FRGathererDefn}
|
|
11
11
|
*/
|
|
12
12
|
function isFRGathererDefn(gathererDefn) {
|
|
13
13
|
return 'meta' in gathererDefn.instance;
|
|
@@ -17,8 +17,8 @@ function isFRGathererDefn(gathererDefn) {
|
|
|
17
17
|
* Determines if the artifact dependency direction is valid. The dependency's minimum supported mode
|
|
18
18
|
* must be less than or equal to the dependent's.
|
|
19
19
|
*
|
|
20
|
-
* @param {LH.Config.
|
|
21
|
-
* @param {LH.Config.
|
|
20
|
+
* @param {LH.Config.FRGathererDefn} dependent The artifact that depends on the other.
|
|
21
|
+
* @param {LH.Config.FRGathererDefn} dependency The artifact that is being depended on by the other.
|
|
22
22
|
* @return {boolean}
|
|
23
23
|
*/
|
|
24
24
|
function isValidArtifactDependency(dependent, dependency) {
|
|
@@ -5,12 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
'use strict';
|
|
7
7
|
|
|
8
|
-
const
|
|
9
|
-
const isEqual = require('lodash.isequal');
|
|
10
|
-
const {
|
|
11
|
-
getBenchmarkIndex,
|
|
12
|
-
getEnvironmentWarnings,
|
|
13
|
-
} = require('../../gather/driver/environment.js');
|
|
8
|
+
const {getBrowserVersion, getBenchmarkIndex} = require('../../gather/driver/environment.js');
|
|
14
9
|
|
|
15
10
|
/**
|
|
16
11
|
* @param {LH.Config.FRConfig} config
|
|
@@ -18,73 +13,43 @@ const {
|
|
|
18
13
|
* @return {Promise<LH.BaseArtifacts>}
|
|
19
14
|
*/
|
|
20
15
|
async function getBaseArtifacts(config, driver) {
|
|
16
|
+
const HostUserAgent = (await getBrowserVersion(driver.defaultSession)).userAgent;
|
|
17
|
+
|
|
18
|
+
// Whether Lighthouse was run on a mobile device (i.e. not on a desktop machine).
|
|
19
|
+
const HostFormFactor =
|
|
20
|
+
HostUserAgent.includes('Android') || HostUserAgent.includes('Mobile') ? 'mobile' : 'desktop';
|
|
21
|
+
|
|
21
22
|
const BenchmarkIndex = await getBenchmarkIndex(driver.executionContext);
|
|
22
23
|
|
|
24
|
+
/** @type {Array<string | LH.IcuMessage>} */
|
|
25
|
+
const LighthouseRunWarnings = [];
|
|
26
|
+
|
|
27
|
+
// TODO(FR-COMPAT): support slow host CPU warning
|
|
28
|
+
// TODO(FR-COMPAT): support redirected URL warning
|
|
29
|
+
|
|
23
30
|
return {
|
|
24
31
|
// Meta artifacts.
|
|
25
32
|
fetchTime: new Date().toJSON(),
|
|
26
33
|
Timing: [],
|
|
27
|
-
LighthouseRunWarnings
|
|
34
|
+
LighthouseRunWarnings,
|
|
28
35
|
settings: config.settings,
|
|
29
36
|
// Environment artifacts that can always be computed.
|
|
37
|
+
HostFormFactor,
|
|
38
|
+
HostUserAgent,
|
|
30
39
|
BenchmarkIndex,
|
|
31
40
|
// Contextual artifacts whose collection changes based on gather mode.
|
|
32
41
|
URL: {requestedUrl: '', finalUrl: ''},
|
|
33
|
-
PageLoadError: null,
|
|
42
|
+
PageLoadError: null, // TODO(FR-COMPAT): support PageLoadError
|
|
34
43
|
// Artifacts that have been replaced by regular gatherers in Fraggle Rock.
|
|
35
|
-
HostFormFactor: 'mobile',
|
|
36
|
-
HostUserAgent: '',
|
|
37
44
|
Stacks: [],
|
|
38
45
|
NetworkUserAgent: '',
|
|
39
|
-
WebAppManifest: null,
|
|
40
|
-
InstallabilityErrors: {errors: []},
|
|
46
|
+
WebAppManifest: null, // replaced by standard gatherer
|
|
47
|
+
InstallabilityErrors: {errors: []}, // replaced by standard gatherer
|
|
41
48
|
traces: {},
|
|
42
49
|
devtoolsLogs: {},
|
|
43
50
|
};
|
|
44
51
|
}
|
|
45
52
|
|
|
46
|
-
/**
|
|
47
|
-
* Deduplicates identical warnings.
|
|
48
|
-
* @param {Array<string | LH.IcuMessage>} warnings
|
|
49
|
-
* @return {Array<string | LH.IcuMessage>}
|
|
50
|
-
*/
|
|
51
|
-
function deduplicateWarnings(warnings) {
|
|
52
|
-
/** @type {Array<string | LH.IcuMessage>} */
|
|
53
|
-
const unique = [];
|
|
54
|
-
|
|
55
|
-
for (const warning of warnings) {
|
|
56
|
-
if (unique.some(existing => isEqual(warning, existing))) continue;
|
|
57
|
-
unique.push(warning);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
return unique;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* @param {LH.FRBaseArtifacts} baseArtifacts
|
|
65
|
-
* @param {Partial<LH.Artifacts>} gathererArtifacts
|
|
66
|
-
* @return {LH.Artifacts}
|
|
67
|
-
*/
|
|
68
|
-
function finalizeArtifacts(baseArtifacts, gathererArtifacts) {
|
|
69
|
-
const warnings = baseArtifacts.LighthouseRunWarnings
|
|
70
|
-
.concat(gathererArtifacts.LighthouseRunWarnings || [])
|
|
71
|
-
.concat(getEnvironmentWarnings({settings: baseArtifacts.settings, baseArtifacts}));
|
|
72
|
-
|
|
73
|
-
// Cast to remove the partial from gathererArtifacts.
|
|
74
|
-
const artifacts = /** @type {LH.Artifacts} */ ({...baseArtifacts, ...gathererArtifacts});
|
|
75
|
-
|
|
76
|
-
// Set the post-run meta artifacts.
|
|
77
|
-
artifacts.Timing = log.getTimeEntries();
|
|
78
|
-
artifacts.LighthouseRunWarnings = deduplicateWarnings(warnings);
|
|
79
|
-
|
|
80
|
-
// Check that the runner remembered to mutate the special-case URL artifact.
|
|
81
|
-
if (!artifacts.URL.requestedUrl) throw new Error('Runner did not set requestedUrl');
|
|
82
|
-
if (!artifacts.URL.finalUrl) throw new Error('Runner did not set finalUrl');
|
|
83
|
-
|
|
84
|
-
return artifacts;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
53
|
module.exports = {
|
|
88
54
|
getBaseArtifacts,
|
|
89
|
-
finalizeArtifacts,
|
|
90
55
|
};
|
|
@@ -19,7 +19,7 @@ const storage = require('../../gather/driver/storage.js');
|
|
|
19
19
|
const emulation = require('../../lib/emulation.js');
|
|
20
20
|
const {defaultNavigationConfig} = require('../../config/constants.js');
|
|
21
21
|
const {initializeConfig} = require('../config/config.js');
|
|
22
|
-
const {getBaseArtifacts
|
|
22
|
+
const {getBaseArtifacts} = require('./base-artifacts.js');
|
|
23
23
|
const i18n = require('../../lib/i18n/i18n.js');
|
|
24
24
|
const LighthouseError = require('../../lib/lh-error.js');
|
|
25
25
|
const {getPageLoadError} = require('../../lib/navigation-error.js');
|
|
@@ -126,7 +126,7 @@ async function _collectNetworkRecords(navigationContext, phaseState) {
|
|
|
126
126
|
* @param {PhaseState} phaseState
|
|
127
127
|
* @param {UnPromise<ReturnType<typeof _setupNavigation>>} setupResult
|
|
128
128
|
* @param {UnPromise<ReturnType<typeof _navigate>>} navigateResult
|
|
129
|
-
* @return {Promise<{
|
|
129
|
+
* @return {Promise<{artifacts: Partial<LH.GathererArtifacts>, warnings: Array<LH.IcuMessage>, pageLoadError: LH.LighthouseError | undefined}>}
|
|
130
130
|
*/
|
|
131
131
|
async function _computeNavigationResult(
|
|
132
132
|
navigationContext,
|
|
@@ -150,17 +150,12 @@ async function _computeNavigationResult(
|
|
|
150
150
|
const localizedMessage = i18n.getFormatted(pageLoadError.friendlyMessage, locale);
|
|
151
151
|
log.error('NavigationRunner', localizedMessage, navigationContext.requestedUrl);
|
|
152
152
|
|
|
153
|
-
return {
|
|
154
|
-
finalUrl,
|
|
155
|
-
pageLoadError,
|
|
156
|
-
artifacts: {},
|
|
157
|
-
warnings: [...warnings, pageLoadError.friendlyMessage],
|
|
158
|
-
};
|
|
153
|
+
return {artifacts: {}, warnings: [...warnings, pageLoadError.friendlyMessage], pageLoadError};
|
|
159
154
|
} else {
|
|
160
155
|
await collectPhaseArtifacts({phase: 'getArtifact', ...phaseState});
|
|
161
156
|
|
|
162
157
|
const artifacts = await awaitArtifacts(phaseState.artifactState);
|
|
163
|
-
return {
|
|
158
|
+
return {artifacts, warnings, pageLoadError: undefined};
|
|
164
159
|
}
|
|
165
160
|
}
|
|
166
161
|
|
|
@@ -199,8 +194,6 @@ async function _navigations({driver, config, requestedUrl, computedCache}) {
|
|
|
199
194
|
|
|
200
195
|
/** @type {Partial<LH.FRArtifacts & LH.FRBaseArtifacts>} */
|
|
201
196
|
const artifacts = {};
|
|
202
|
-
/** @type {Array<LH.IcuMessage>} */
|
|
203
|
-
const LighthouseRunWarnings = [];
|
|
204
197
|
|
|
205
198
|
for (const navigation of config.navigations) {
|
|
206
199
|
const navigationContext = {
|
|
@@ -212,20 +205,16 @@ async function _navigations({driver, config, requestedUrl, computedCache}) {
|
|
|
212
205
|
};
|
|
213
206
|
|
|
214
207
|
const navigationResult = await _navigation(navigationContext);
|
|
215
|
-
if (navigation.loadFailureMode === 'fatal') {
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
break;
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
artifacts.URL = {requestedUrl, finalUrl: navigationResult.finalUrl};
|
|
208
|
+
if (navigationResult.pageLoadError && navigation.loadFailureMode === 'fatal') {
|
|
209
|
+
artifacts.PageLoadError = navigationResult.pageLoadError;
|
|
210
|
+
break;
|
|
222
211
|
}
|
|
223
212
|
|
|
224
|
-
|
|
213
|
+
// TODO(FR-COMPAT): merge RunWarnings between navigations
|
|
225
214
|
Object.assign(artifacts, navigationResult.artifacts);
|
|
226
215
|
}
|
|
227
216
|
|
|
228
|
-
return {artifacts
|
|
217
|
+
return {artifacts};
|
|
229
218
|
}
|
|
230
219
|
|
|
231
220
|
/**
|
|
@@ -254,7 +243,7 @@ async function navigation(options) {
|
|
|
254
243
|
const {artifacts} = await _navigations({driver, config, requestedUrl, computedCache});
|
|
255
244
|
await _cleanup({driver, config, requestedUrl});
|
|
256
245
|
|
|
257
|
-
return
|
|
246
|
+
return /** @type {LH.Artifacts} */ ({...baseArtifacts, ...artifacts}); // Cast to drop Partial<>
|
|
258
247
|
},
|
|
259
248
|
{
|
|
260
249
|
url: requestedUrl,
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
/**
|
|
9
9
|
* @typedef CollectPhaseArtifactOptions
|
|
10
10
|
* @property {import('./driver.js')} driver
|
|
11
|
-
* @property {Array<LH.Config.
|
|
11
|
+
* @property {Array<LH.Config.ArtifactDefn>} artifactDefinitions
|
|
12
12
|
* @property {ArtifactState} artifactState
|
|
13
13
|
* @property {LH.Gatherer.FRGatherPhase} phase
|
|
14
14
|
* @property {LH.Gatherer.GatherMode} gatherMode
|
|
@@ -99,7 +99,7 @@ async function collectPhaseArtifacts(options) {
|
|
|
99
99
|
}
|
|
100
100
|
|
|
101
101
|
/**
|
|
102
|
-
* @param {LH.Config.
|
|
102
|
+
* @param {LH.Config.ArtifactDefn} artifact
|
|
103
103
|
* @param {Record<string, LH.Gatherer.PhaseResult>} artifactsById
|
|
104
104
|
* @return {Promise<Dependencies>}
|
|
105
105
|
*/
|
|
@@ -13,7 +13,7 @@ const {
|
|
|
13
13
|
awaitArtifacts,
|
|
14
14
|
} = require('./runner-helpers.js');
|
|
15
15
|
const {initializeConfig} = require('../config/config.js');
|
|
16
|
-
const {getBaseArtifacts
|
|
16
|
+
const {getBaseArtifacts} = require('./base-artifacts.js');
|
|
17
17
|
|
|
18
18
|
/** @param {{page: import('puppeteer').Page, config?: LH.Config.Json}} options */
|
|
19
19
|
async function snapshot(options) {
|
|
@@ -44,7 +44,7 @@ async function snapshot(options) {
|
|
|
44
44
|
});
|
|
45
45
|
|
|
46
46
|
const artifacts = await awaitArtifacts(artifactState);
|
|
47
|
-
return
|
|
47
|
+
return /** @type {LH.Artifacts} */ ({...baseArtifacts, ...artifacts}); // Cast to drop Partial<>
|
|
48
48
|
},
|
|
49
49
|
{
|
|
50
50
|
url,
|
|
@@ -13,7 +13,7 @@ const {
|
|
|
13
13
|
awaitArtifacts,
|
|
14
14
|
} = require('./runner-helpers.js');
|
|
15
15
|
const {initializeConfig} = require('../config/config.js');
|
|
16
|
-
const {getBaseArtifacts
|
|
16
|
+
const {getBaseArtifacts} = require('./base-artifacts.js');
|
|
17
17
|
|
|
18
18
|
/**
|
|
19
19
|
* @param {{page: import('puppeteer').Page, config?: LH.Config.Json}} options
|
|
@@ -56,7 +56,7 @@ async function startTimespan(options) {
|
|
|
56
56
|
await collectPhaseArtifacts({phase: 'getArtifact', ...phaseOptions});
|
|
57
57
|
|
|
58
58
|
const artifacts = await awaitArtifacts(artifactState);
|
|
59
|
-
return
|
|
59
|
+
return /** @type {LH.Artifacts} */ ({...baseArtifacts, ...artifacts}); // Cast to drop Partial<>
|
|
60
60
|
},
|
|
61
61
|
{
|
|
62
62
|
url: finalUrl,
|
|
@@ -127,9 +127,6 @@ async function prepareNetworkForNavigation(session, settings, navigation) {
|
|
|
127
127
|
* @param {LH.Config.Settings} settings
|
|
128
128
|
*/
|
|
129
129
|
async function prepareTargetForNavigationMode(driver, settings) {
|
|
130
|
-
// Enable network domain here so future calls to `emulate()` don't clear cache (#12631)
|
|
131
|
-
await driver.defaultSession.sendCommand('Network.enable');
|
|
132
|
-
|
|
133
130
|
// Emulate our target device screen and user agent.
|
|
134
131
|
await emulation.emulate(driver.defaultSession, settings);
|
|
135
132
|
|
|
@@ -146,6 +146,7 @@ class Fetcher {
|
|
|
146
146
|
* @return {Promise<{stream: LH.Crdp.IO.StreamHandle|null, status: number|null}>}
|
|
147
147
|
*/
|
|
148
148
|
async _loadNetworkResource(url) {
|
|
149
|
+
await this.session.sendCommand('Network.enable');
|
|
149
150
|
const frameTreeResponse = await this.session.sendCommand('Page.getFrameTree');
|
|
150
151
|
const networkResponse = await this.session.sendCommand('Network.loadNetworkResource', {
|
|
151
152
|
frameId: frameTreeResponse.frameTree.frame.id,
|
|
@@ -155,6 +156,7 @@ class Fetcher {
|
|
|
155
156
|
includeCredentials: true,
|
|
156
157
|
},
|
|
157
158
|
});
|
|
159
|
+
await this.session.sendCommand('Network.disable');
|
|
158
160
|
|
|
159
161
|
return {
|
|
160
162
|
stream: networkResponse.resource.success ? (networkResponse.resource.stream || null) : null,
|
|
@@ -20,7 +20,6 @@ const WebAppManifest = require('./gatherers/web-app-manifest.js');
|
|
|
20
20
|
const InstallabilityErrors = require('./gatherers/installability-errors.js');
|
|
21
21
|
const NetworkUserAgent = require('./gatherers/network-user-agent.js');
|
|
22
22
|
const Stacks = require('./gatherers/stacks.js');
|
|
23
|
-
const {finalizeArtifacts} = require('../fraggle-rock/gather/base-artifacts.js');
|
|
24
23
|
|
|
25
24
|
/** @typedef {import('../gather/driver.js')} Driver */
|
|
26
25
|
/** @typedef {import('../lib/arbitrary-equality-map.js')} ArbitraryEqualityMap */
|
|
@@ -447,6 +446,18 @@ class GatherRunner {
|
|
|
447
446
|
log.timeEnd(status);
|
|
448
447
|
}
|
|
449
448
|
|
|
449
|
+
/**
|
|
450
|
+
* Finalize baseArtifacts after gathering is fully complete.
|
|
451
|
+
* @param {LH.BaseArtifacts} baseArtifacts
|
|
452
|
+
*/
|
|
453
|
+
static finalizeBaseArtifacts(baseArtifacts) {
|
|
454
|
+
// Take only unique LighthouseRunWarnings.
|
|
455
|
+
baseArtifacts.LighthouseRunWarnings = Array.from(new Set(baseArtifacts.LighthouseRunWarnings));
|
|
456
|
+
|
|
457
|
+
// Take the timing entries we've gathered so far.
|
|
458
|
+
baseArtifacts.Timing = log.getTimeEntries();
|
|
459
|
+
}
|
|
460
|
+
|
|
450
461
|
/**
|
|
451
462
|
* @param {Array<LH.Config.Pass>} passConfigs
|
|
452
463
|
* @param {{driver: Driver, requestedUrl: string, settings: LH.Config.Settings, computedCache: Map<string, ArbitraryEqualityMap>}} options
|
|
@@ -504,7 +515,8 @@ class GatherRunner {
|
|
|
504
515
|
}
|
|
505
516
|
|
|
506
517
|
await GatherRunner.disposeDriver(driver, options);
|
|
507
|
-
|
|
518
|
+
GatherRunner.finalizeBaseArtifacts(baseArtifacts);
|
|
519
|
+
return /** @type {LH.Artifacts} */ ({...baseArtifacts, ...artifacts}); // Cast to drop Partial<>.
|
|
508
520
|
} catch (err) {
|
|
509
521
|
// Clean up on error. Don't await so that the root error, not a disposal error, is shown.
|
|
510
522
|
GatherRunner.disposeDriver(driver, options);
|
|
@@ -12,8 +12,9 @@
|
|
|
12
12
|
const log = require('lighthouse-logger');
|
|
13
13
|
const FRGatherer = require('../../fraggle-rock/gather/base-gatherer.js');
|
|
14
14
|
const pageFunctions = require('../../lib/page-functions.js');
|
|
15
|
-
const
|
|
15
|
+
const DevtoolsLog = require('./devtools-log.js');
|
|
16
16
|
const FontSize = require('./seo/font-size.js');
|
|
17
|
+
const NetworkRecords = require('../../computed/network-records.js');
|
|
17
18
|
|
|
18
19
|
/* global window, getElementsInDocument, Image, getNodeDetails, ShadowRoot */
|
|
19
20
|
|
|
@@ -190,7 +191,7 @@ function findSizeDeclaration(rule, property) {
|
|
|
190
191
|
*
|
|
191
192
|
* @param {Array<LH.Crdp.CSS.RuleMatch>|undefined} matchedCSSRules
|
|
192
193
|
* @param {string} property
|
|
193
|
-
* @
|
|
194
|
+
* @returns {string | undefined}
|
|
194
195
|
*/
|
|
195
196
|
function findMostSpecificCSSRule(matchedCSSRules, property) {
|
|
196
197
|
/** @param {LH.Crdp.CSS.CSSStyle} declaration */
|
|
@@ -204,7 +205,7 @@ function findMostSpecificCSSRule(matchedCSSRules, property) {
|
|
|
204
205
|
/**
|
|
205
206
|
* @param {LH.Crdp.CSS.GetMatchedStylesForNodeResponse} matched CSS rules}
|
|
206
207
|
* @param {string} property
|
|
207
|
-
* @
|
|
208
|
+
* @returns {string | null}
|
|
208
209
|
*/
|
|
209
210
|
function getEffectiveSizingRule({attributesStyle, inlineStyle, matchedCSSRules}, property) {
|
|
210
211
|
// CSS sizing can't be inherited.
|
|
@@ -223,21 +224,11 @@ function getEffectiveSizingRule({attributesStyle, inlineStyle, matchedCSSRules},
|
|
|
223
224
|
return null;
|
|
224
225
|
}
|
|
225
226
|
|
|
226
|
-
/**
|
|
227
|
-
* @param {LH.Artifacts.ImageElement} element
|
|
228
|
-
* @return {number}
|
|
229
|
-
*/
|
|
230
|
-
function getPixelArea(element) {
|
|
231
|
-
if (element.naturalDimensions) {
|
|
232
|
-
return element.naturalDimensions.height * element.naturalDimensions.width;
|
|
233
|
-
}
|
|
234
|
-
return element.displayedHeight * element.displayedWidth;
|
|
235
|
-
}
|
|
236
|
-
|
|
237
227
|
class ImageElements extends FRGatherer {
|
|
238
|
-
/** @type {LH.Gatherer.GathererMeta} */
|
|
228
|
+
/** @type {LH.Gatherer.GathererMeta<'DevtoolsLog'>} */
|
|
239
229
|
meta = {
|
|
240
|
-
supportedModes: ['
|
|
230
|
+
supportedModes: ['navigation'],
|
|
231
|
+
dependencies: {DevtoolsLog: DevtoolsLog.symbol},
|
|
241
232
|
};
|
|
242
233
|
|
|
243
234
|
constructor() {
|
|
@@ -298,19 +289,40 @@ class ImageElements extends FRGatherer {
|
|
|
298
289
|
}
|
|
299
290
|
}
|
|
300
291
|
|
|
292
|
+
/**
|
|
293
|
+
* @param {LH.Artifacts.NetworkRequest[]} networkRecords
|
|
294
|
+
*/
|
|
295
|
+
indexNetworkRecords(networkRecords) {
|
|
296
|
+
return networkRecords.reduce((map, record) => {
|
|
297
|
+
// An image response in newer formats is sometimes incorrectly marked as "application/octet-stream",
|
|
298
|
+
// so respect the extension too.
|
|
299
|
+
const isImage = /^image/.test(record.mimeType) || /\.(avif|webp)$/i.test(record.url);
|
|
300
|
+
// The network record is only valid for size information if it finished with a successful status
|
|
301
|
+
// code that indicates a complete image response.
|
|
302
|
+
if (isImage && record.finished && record.statusCode === 200) {
|
|
303
|
+
map[record.url] = record;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
return map;
|
|
307
|
+
}, /** @type {Record<string, LH.Artifacts.NetworkRequest>} */ ({}));
|
|
308
|
+
}
|
|
309
|
+
|
|
301
310
|
/**
|
|
302
311
|
*
|
|
303
312
|
* @param {LH.Gatherer.FRTransitionalDriver} driver
|
|
304
313
|
* @param {LH.Artifacts.ImageElement[]} elements
|
|
314
|
+
* @param {Record<string, LH.Artifacts.NetworkRequest>} indexedNetworkRecords
|
|
305
315
|
*/
|
|
306
|
-
async collectExtraDetails(driver, elements) {
|
|
316
|
+
async collectExtraDetails(driver, elements, indexedNetworkRecords) {
|
|
307
317
|
// Don't do more than 5s of this expensive devtools protocol work. See #11289
|
|
308
318
|
let reachedGatheringBudget = false;
|
|
309
319
|
setTimeout(_ => (reachedGatheringBudget = true), 5000);
|
|
310
320
|
let skippedCount = 0;
|
|
311
321
|
|
|
312
322
|
for (const element of elements) {
|
|
313
|
-
|
|
323
|
+
// Pull some of our information directly off the network record.
|
|
324
|
+
const networkRecord = indexedNetworkRecords[element.src];
|
|
325
|
+
element.mimeType = networkRecord && networkRecord.mimeType;
|
|
314
326
|
|
|
315
327
|
if (reachedGatheringBudget) {
|
|
316
328
|
skippedCount++;
|
|
@@ -323,7 +335,8 @@ class ImageElements extends FRGatherer {
|
|
|
323
335
|
}
|
|
324
336
|
// Images within `picture` behave strangely and natural size information isn't accurate,
|
|
325
337
|
// CSS images have no natural size information at all. Try to get the actual size if we can.
|
|
326
|
-
if
|
|
338
|
+
// Additional fetch is expensive; don't bother if we don't have a networkRecord for the image.
|
|
339
|
+
if ((element.isPicture || element.isCss || element.srcset) && networkRecord) {
|
|
327
340
|
await this.fetchElementWithSizeInformation(driver, element);
|
|
328
341
|
}
|
|
329
342
|
}
|
|
@@ -335,11 +348,13 @@ class ImageElements extends FRGatherer {
|
|
|
335
348
|
|
|
336
349
|
/**
|
|
337
350
|
* @param {LH.Gatherer.FRTransitionalContext} context
|
|
351
|
+
* @param {LH.Artifacts.NetworkRequest[]} networkRecords
|
|
338
352
|
* @return {Promise<LH.Artifacts['ImageElements']>}
|
|
339
353
|
*/
|
|
340
|
-
async
|
|
354
|
+
async _getArtifact(context, networkRecords) {
|
|
341
355
|
const session = context.driver.defaultSession;
|
|
342
356
|
const executionContext = context.driver.executionContext;
|
|
357
|
+
const indexedNetworkRecords = this.indexNetworkRecords(networkRecords);
|
|
343
358
|
|
|
344
359
|
const elements = await executionContext.evaluate(collectImageElementInfo, {
|
|
345
360
|
args: [],
|
|
@@ -360,11 +375,14 @@ class ImageElements extends FRGatherer {
|
|
|
360
375
|
session.sendCommand('DOM.getDocument', {depth: -1, pierce: true}),
|
|
361
376
|
]);
|
|
362
377
|
|
|
363
|
-
//
|
|
364
|
-
|
|
365
|
-
|
|
378
|
+
// Sort (in-place) as largest images descending.
|
|
379
|
+
elements.sort((a, b) => {
|
|
380
|
+
const aRecord = indexedNetworkRecords[a.src] || {};
|
|
381
|
+
const bRecord = indexedNetworkRecords[b.src] || {};
|
|
382
|
+
return bRecord.resourceSize - aRecord.resourceSize;
|
|
383
|
+
});
|
|
366
384
|
|
|
367
|
-
await this.collectExtraDetails(context.driver, elements);
|
|
385
|
+
await this.collectExtraDetails(context.driver, elements, indexedNetworkRecords);
|
|
368
386
|
|
|
369
387
|
await Promise.all([
|
|
370
388
|
session.sendCommand('DOM.disable'),
|
|
@@ -373,6 +391,25 @@ class ImageElements extends FRGatherer {
|
|
|
373
391
|
|
|
374
392
|
return elements;
|
|
375
393
|
}
|
|
394
|
+
|
|
395
|
+
/**
|
|
396
|
+
* @param {LH.Gatherer.FRTransitionalContext<'DevtoolsLog'>} context
|
|
397
|
+
* @return {Promise<LH.Artifacts['ImageElements']>}
|
|
398
|
+
*/
|
|
399
|
+
async getArtifact(context) {
|
|
400
|
+
const devtoolsLog = context.dependencies.DevtoolsLog;
|
|
401
|
+
const networkRecords = await NetworkRecords.request(devtoolsLog, context);
|
|
402
|
+
return this._getArtifact(context, networkRecords);
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
/**
|
|
406
|
+
* @param {LH.Gatherer.PassContext} passContext
|
|
407
|
+
* @param {LH.Gatherer.LoadData} loadData
|
|
408
|
+
* @return {Promise<LH.Artifacts['ImageElements']>}
|
|
409
|
+
*/
|
|
410
|
+
async afterPass(passContext, loadData) {
|
|
411
|
+
return this._getArtifact({...passContext, dependencies: {}}, loadData.networkRecords);
|
|
412
|
+
}
|
|
376
413
|
}
|
|
377
414
|
|
|
378
415
|
module.exports = ImageElements;
|
|
@@ -112,7 +112,7 @@ class InspectorIssues extends FRGatherer {
|
|
|
112
112
|
|
|
113
113
|
/**
|
|
114
114
|
* @param {LH.Gatherer.FRTransitionalContext<'DevtoolsLog'>} context
|
|
115
|
-
* @
|
|
115
|
+
* @returns {Promise<LH.Artifacts['InspectorIssues']>}
|
|
116
116
|
*/
|
|
117
117
|
async getArtifact(context) {
|
|
118
118
|
const devtoolsLog = context.dependencies.DevtoolsLog;
|
|
@@ -123,7 +123,7 @@ class InspectorIssues extends FRGatherer {
|
|
|
123
123
|
/**
|
|
124
124
|
* @param {LH.Gatherer.PassContext} passContext
|
|
125
125
|
* @param {LH.Gatherer.LoadData} loadData
|
|
126
|
-
* @
|
|
126
|
+
* @returns {Promise<LH.Artifacts['InspectorIssues']>}
|
|
127
127
|
*/
|
|
128
128
|
async afterPass(passContext, loadData) {
|
|
129
129
|
await this.stopInstrumentation({...passContext, dependencies: {}});
|
|
@@ -5,14 +5,10 @@
|
|
|
5
5
|
*/
|
|
6
6
|
'use strict';
|
|
7
7
|
|
|
8
|
-
const
|
|
9
|
-
const NetworkRecords = require('../../computed/network-records.js');
|
|
8
|
+
const Gatherer = require('./gatherer.js');
|
|
10
9
|
const NetworkAnalyzer = require('../../lib/dependency-graph/simulator/network-analyzer.js');
|
|
11
10
|
const NetworkRequest = require('../../lib/network-request.js');
|
|
12
11
|
const pageFunctions = require('../../lib/page-functions.js');
|
|
13
|
-
const {fetchResponseBodyFromCache} = require('../driver/network.js');
|
|
14
|
-
const DevtoolsLog = require('./devtools-log.js');
|
|
15
|
-
const HostFormFactor = require('./host-form-factor.js');
|
|
16
12
|
|
|
17
13
|
/* global getNodeDetails */
|
|
18
14
|
|
|
@@ -66,25 +62,17 @@ async function runInSeriesOrParallel(values, promiseMapper, runInSeries) {
|
|
|
66
62
|
/**
|
|
67
63
|
* @fileoverview Gets JavaScript file contents.
|
|
68
64
|
*/
|
|
69
|
-
class ScriptElements extends
|
|
70
|
-
/** @type {LH.Gatherer.GathererMeta<'DevtoolsLog'|'HostFormFactor'>} */
|
|
71
|
-
meta = {
|
|
72
|
-
supportedModes: ['timespan', 'navigation'],
|
|
73
|
-
dependencies: {DevtoolsLog: DevtoolsLog.symbol, HostFormFactor: HostFormFactor.symbol},
|
|
74
|
-
}
|
|
75
|
-
|
|
65
|
+
class ScriptElements extends Gatherer {
|
|
76
66
|
/**
|
|
77
|
-
* @param {LH.Gatherer.
|
|
78
|
-
* @param {LH.
|
|
79
|
-
* @param {LH.Artifacts['HostFormFactor']} formFactor
|
|
67
|
+
* @param {LH.Gatherer.PassContext} passContext
|
|
68
|
+
* @param {LH.Gatherer.LoadData} loadData
|
|
80
69
|
* @return {Promise<LH.Artifacts['ScriptElements']>}
|
|
81
70
|
*/
|
|
82
|
-
async
|
|
83
|
-
const
|
|
84
|
-
const
|
|
85
|
-
const mainResource = NetworkAnalyzer.findOptionalMainDocument(networkRecords, context.url);
|
|
71
|
+
async afterPass(passContext, loadData) {
|
|
72
|
+
const driver = passContext.driver;
|
|
73
|
+
const mainResource = NetworkAnalyzer.findMainDocument(loadData.networkRecords, passContext.url);
|
|
86
74
|
|
|
87
|
-
const scripts = await executionContext.evaluate(collectAllScriptElements, {
|
|
75
|
+
const scripts = await driver.executionContext.evaluate(collectAllScriptElements, {
|
|
88
76
|
args: [],
|
|
89
77
|
useIsolation: true,
|
|
90
78
|
deps: [
|
|
@@ -94,10 +82,10 @@ class ScriptElements extends FRGatherer {
|
|
|
94
82
|
});
|
|
95
83
|
|
|
96
84
|
for (const script of scripts) {
|
|
97
|
-
if (
|
|
85
|
+
if (script.content) script.requestId = mainResource.requestId;
|
|
98
86
|
}
|
|
99
87
|
|
|
100
|
-
const scriptRecords = networkRecords
|
|
88
|
+
const scriptRecords = loadData.networkRecords
|
|
101
89
|
// Ignore records from OOPIFs
|
|
102
90
|
.filter(record => !record.sessionId)
|
|
103
91
|
// Only get the content of script requests
|
|
@@ -107,9 +95,8 @@ class ScriptElements extends FRGatherer {
|
|
|
107
95
|
// record at a time.
|
|
108
96
|
const scriptRecordContents = await runInSeriesOrParallel(
|
|
109
97
|
scriptRecords,
|
|
110
|
-
record =>
|
|
111
|
-
|
|
112
|
-
);
|
|
98
|
+
record => driver.getRequestContent(record.requestId).catch(() => ''),
|
|
99
|
+
passContext.baseArtifacts.HostFormFactor === 'mobile' /* runInSeries*/ );
|
|
113
100
|
|
|
114
101
|
for (let i = 0; i < scriptRecords.length; i++) {
|
|
115
102
|
const record = scriptRecords[i];
|
|
@@ -136,26 +123,6 @@ class ScriptElements extends FRGatherer {
|
|
|
136
123
|
}
|
|
137
124
|
return scripts;
|
|
138
125
|
}
|
|
139
|
-
|
|
140
|
-
/**
|
|
141
|
-
* @param {LH.Gatherer.FRTransitionalContext<'DevtoolsLog'|'HostFormFactor'>} context
|
|
142
|
-
*/
|
|
143
|
-
async getArtifact(context) {
|
|
144
|
-
const devtoolsLog = context.dependencies.DevtoolsLog;
|
|
145
|
-
const formFactor = context.dependencies.HostFormFactor;
|
|
146
|
-
const networkRecords = await NetworkRecords.request(devtoolsLog, context);
|
|
147
|
-
return this._getArtifact(context, networkRecords, formFactor);
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
/**
|
|
151
|
-
* @param {LH.Gatherer.PassContext} passContext
|
|
152
|
-
* @param {LH.Gatherer.LoadData} loadData
|
|
153
|
-
*/
|
|
154
|
-
async afterPass(passContext, loadData) {
|
|
155
|
-
const networkRecords = loadData.networkRecords;
|
|
156
|
-
const formFactor = passContext.baseArtifacts.HostFormFactor;
|
|
157
|
-
return this._getArtifact({...passContext, dependencies: {}}, networkRecords, formFactor);
|
|
158
|
-
}
|
|
159
126
|
}
|
|
160
127
|
|
|
161
128
|
module.exports = ScriptElements;
|
|
@@ -68,7 +68,7 @@ function computeSelectorSpecificity(selector) {
|
|
|
68
68
|
*
|
|
69
69
|
* @param {Array<LH.Crdp.CSS.RuleMatch>} matchedCSSRules
|
|
70
70
|
* @param {function(LH.Crdp.CSS.CSSStyle):boolean|string|undefined} isDeclarationOfInterest
|
|
71
|
-
* @
|
|
71
|
+
* @returns {NodeFontData['cssRule']|undefined}
|
|
72
72
|
*/
|
|
73
73
|
function findMostSpecificMatchedCSSRule(matchedCSSRules = [], isDeclarationOfInterest) {
|
|
74
74
|
let maxSpecificity = -Infinity;
|
|
@@ -105,7 +105,7 @@ function findMostSpecificMatchedCSSRule(matchedCSSRules = [], isDeclarationOfInt
|
|
|
105
105
|
* Finds the most specific directly matched CSS font-size rule from the list.
|
|
106
106
|
*
|
|
107
107
|
* @param {Array<LH.Crdp.CSS.InheritedStyleEntry>} [inheritedEntries]
|
|
108
|
-
* @
|
|
108
|
+
* @returns {NodeFontData['cssRule']|undefined}
|
|
109
109
|
*/
|
|
110
110
|
function findInheritedCSSRule(inheritedEntries = []) {
|
|
111
111
|
// The inherited array contains the array of matched rules for all parents in ascending tree order.
|
|
@@ -126,7 +126,7 @@ function findInheritedCSSRule(inheritedEntries = []) {
|
|
|
126
126
|
*
|
|
127
127
|
* @see https://cs.chromium.org/chromium/src/third_party/blink/renderer/devtools/front_end/sdk/CSSMatchedStyles.js?q=CSSMatchedStyles+f:devtools+-f:out&sq=package:chromium&dr=C&l=59-134
|
|
128
128
|
* @param {LH.Crdp.CSS.GetMatchedStylesForNodeResponse} matched CSS rules
|
|
129
|
-
* @
|
|
129
|
+
* @returns {NodeFontData['cssRule']|undefined}
|
|
130
130
|
*/
|
|
131
131
|
function getEffectiveFontRule({attributesStyle, inlineStyle, matchedCSSRules, inherited}) {
|
|
132
132
|
// Inline styles have highest priority
|
|
@@ -148,7 +148,7 @@ function getEffectiveFontRule({attributesStyle, inlineStyle, matchedCSSRules, in
|
|
|
148
148
|
|
|
149
149
|
/**
|
|
150
150
|
* @param {string} text
|
|
151
|
-
* @
|
|
151
|
+
* @returns {number}
|
|
152
152
|
*/
|
|
153
153
|
function getTextLength(text) {
|
|
154
154
|
// Array.from to count symbols not unicode code points. See: #6973
|
|
@@ -158,7 +158,7 @@ function getTextLength(text) {
|
|
|
158
158
|
/**
|
|
159
159
|
* @param {LH.Gatherer.FRProtocolSession} session
|
|
160
160
|
* @param {number} nodeId text node
|
|
161
|
-
* @
|
|
161
|
+
* @returns {Promise<NodeFontData['cssRule']|undefined>}
|
|
162
162
|
*/
|
|
163
163
|
async function fetchSourceRule(session, nodeId) {
|
|
164
164
|
const matchedRules = await session.sendCommand('CSS.getMatchedStylesForNode', {
|