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
|
@@ -16,8 +16,10 @@
|
|
|
16
16
|
* 4. Return all those items in one handy bundle.
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
|
-
/** @typedef {Omit<LH.Artifacts.
|
|
20
|
-
/** @typedef {'
|
|
19
|
+
/** @typedef {Omit<LH.Artifacts.TraceTimes, 'firstContentfulPaint'|'firstContentfulPaintAllFrames'> & {firstContentfulPaint?: number, firstContentfulPaintAllFrames?: number}} TraceTimesWithoutFCP */
|
|
20
|
+
/** @typedef {Omit<TraceTimesWithoutFCP, 'traceEnd'>} TraceTimesWithoutFCPAndTraceEnd */
|
|
21
|
+
/** @typedef {Omit<LH.Artifacts.TraceOfTab, 'firstContentfulPaintEvt'|'firstContentfulPaintAllFramesEvt'|'timings'|'timestamps'> & {timings: TraceTimesWithoutFCP, timestamps: TraceTimesWithoutFCP, firstContentfulPaintEvt?: LH.Artifacts.TraceOfTab['firstContentfulPaintEvt'], firstContentfulPaintAllFramesEvt?: LH.Artifacts.TraceOfTab['largestContentfulPaintAllFramesEvt']}} TraceOfTabWithoutFCP */
|
|
22
|
+
/** @typedef {'lastNavigationStart'|'firstResourceSendRequest'} TimeOriginDeterminationMethod */
|
|
21
23
|
/** @typedef {Omit<LH.TraceEvent, 'name'|'args'> & {name: 'FrameCommittedInBrowser', args: {data: {frame: string, url: string, parent?: string}}}} FrameCommittedEvent */
|
|
22
24
|
/** @typedef {Omit<LH.TraceEvent, 'name'|'args'> & {name: 'largestContentfulPaint::Invalidate'|'largestContentfulPaint::Candidate', args: {data?: {size?: number}, frame: string}}} LCPEvent */
|
|
23
25
|
/** @typedef {Omit<LH.TraceEvent, 'name'|'args'> & {name: 'largestContentfulPaint::Candidate', args: {data: {size: number}, frame: string}}} LCPCandidateEvent */
|
|
@@ -39,10 +41,6 @@ const SCHEDULABLE_TASK_TITLE_ALT2 = 'ThreadControllerImpl::DoWork';
|
|
|
39
41
|
const SCHEDULABLE_TASK_TITLE_ALT3 = 'TaskQueueManager::ProcessTaskFromWorkQueue';
|
|
40
42
|
|
|
41
43
|
class TraceProcessor {
|
|
42
|
-
static get TIMESPAN_MARKER_ID() {
|
|
43
|
-
return '__lighthouseTimespanStart__';
|
|
44
|
-
}
|
|
45
|
-
|
|
46
44
|
/**
|
|
47
45
|
* @return {Error}
|
|
48
46
|
*/
|
|
@@ -64,20 +62,6 @@ class TraceProcessor {
|
|
|
64
62
|
return new Error('No tracingStartedInBrowser event found');
|
|
65
63
|
}
|
|
66
64
|
|
|
67
|
-
/**
|
|
68
|
-
* @return {Error}
|
|
69
|
-
*/
|
|
70
|
-
static createNoFirstContentfulPaintError() {
|
|
71
|
-
return new Error('No FirstContentfulPaint event found');
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
/**
|
|
75
|
-
* @return {Error}
|
|
76
|
-
*/
|
|
77
|
-
static createNoLighthouseMarkerError() {
|
|
78
|
-
return new Error('No Lighthouse timespan marker event found');
|
|
79
|
-
}
|
|
80
|
-
|
|
81
65
|
/**
|
|
82
66
|
* Returns true if the event is a navigation start event of a document whose URL seems valid.
|
|
83
67
|
*
|
|
@@ -391,21 +375,21 @@ class TraceProcessor {
|
|
|
391
375
|
}
|
|
392
376
|
|
|
393
377
|
/**
|
|
394
|
-
* Provides the top level events on the main thread with timestamps in ms relative to
|
|
378
|
+
* Provides the top level events on the main thread with timestamps in ms relative to navigation
|
|
395
379
|
* start.
|
|
396
|
-
* @param {LH.Artifacts.
|
|
380
|
+
* @param {LH.Artifacts.TraceOfTab} tabTrace
|
|
397
381
|
* @param {number=} startTime Optional start time (in ms relative to timeOrigin) of range of interest. Defaults to 0.
|
|
398
382
|
* @param {number=} endTime Optional end time (in ms relative to timeOrigin) of range of interest. Defaults to trace end.
|
|
399
383
|
* @return {Array<ToplevelEvent>}
|
|
400
384
|
*/
|
|
401
|
-
static getMainThreadTopLevelEvents(
|
|
385
|
+
static getMainThreadTopLevelEvents(tabTrace, startTime = 0, endTime = Infinity) {
|
|
402
386
|
const topLevelEvents = [];
|
|
403
387
|
// note: mainThreadEvents is already sorted by event start
|
|
404
|
-
for (const event of
|
|
388
|
+
for (const event of tabTrace.mainThreadEvents) {
|
|
405
389
|
if (!this.isScheduleableTask(event) || !event.dur) continue;
|
|
406
390
|
|
|
407
|
-
const start = (event.ts -
|
|
408
|
-
const end = (event.ts + event.dur -
|
|
391
|
+
const start = (event.ts - tabTrace.timeOriginEvt.ts) / 1000;
|
|
392
|
+
const end = (event.ts + event.dur - tabTrace.timeOriginEvt.ts) / 1000;
|
|
409
393
|
if (start > endTime || end < startTime) continue;
|
|
410
394
|
|
|
411
395
|
topLevelEvents.push({
|
|
@@ -592,10 +576,10 @@ class TraceProcessor {
|
|
|
592
576
|
* in milliseconds since the time origin in addition to the standard microsecond monotonic timestamps.
|
|
593
577
|
* @param {LH.Trace} trace
|
|
594
578
|
* @param {{timeOriginDeterminationMethod?: TimeOriginDeterminationMethod}} [options]
|
|
595
|
-
* @return {
|
|
579
|
+
* @return {TraceOfTabWithoutFCP}
|
|
596
580
|
*/
|
|
597
|
-
static
|
|
598
|
-
const {timeOriginDeterminationMethod = '
|
|
581
|
+
static computeTraceOfTab(trace, options) {
|
|
582
|
+
const {timeOriginDeterminationMethod = 'lastNavigationStart'} = options || {};
|
|
599
583
|
|
|
600
584
|
// Parse the trace for our key events and sort them by timestamp. Note: sort
|
|
601
585
|
// *must* be stable to keep events correctly nested.
|
|
@@ -654,6 +638,17 @@ class TraceProcessor {
|
|
|
654
638
|
timeOriginDeterminationMethod
|
|
655
639
|
);
|
|
656
640
|
|
|
641
|
+
// Compute the key frame timings for the main frame.
|
|
642
|
+
const frameTimings = this.computeKeyTimingsForFrame(frameEvents, {timeOriginEvt});
|
|
643
|
+
|
|
644
|
+
// Compute FCP for all frames.
|
|
645
|
+
const fcpAllFramesEvt = frameTreeEvents.find(
|
|
646
|
+
e => e.name === 'firstContentfulPaint' && e.ts > timeOriginEvt.ts
|
|
647
|
+
);
|
|
648
|
+
|
|
649
|
+
// Compute LCP for all frames.
|
|
650
|
+
const lcpAllFramesEvt = this.computeValidLCPAllFrames(frameTreeEvents, timeOriginEvt).lcp;
|
|
651
|
+
|
|
657
652
|
// Subset all trace events to just our tab's process (incl threads other than main)
|
|
658
653
|
// stable-sort events to keep them correctly nested.
|
|
659
654
|
const processEvents = TraceProcessor
|
|
@@ -665,81 +660,41 @@ class TraceProcessor {
|
|
|
665
660
|
// Ensure our traceEnd reflects all page activity.
|
|
666
661
|
const traceEnd = this.computeTraceEnd(trace.traceEvents, timeOriginEvt);
|
|
667
662
|
|
|
663
|
+
/** @param {number|undefined} ts */
|
|
664
|
+
const maybeGetTiming = (ts) => ts === undefined ? undefined : (ts - timeOriginEvt.ts) / 1000;
|
|
668
665
|
// This could be much more concise with object spread, but the consensus is that explicitness is
|
|
669
666
|
// preferred over brevity here.
|
|
670
667
|
return {
|
|
671
668
|
frames,
|
|
672
669
|
mainThreadEvents,
|
|
673
|
-
frameEvents,
|
|
674
670
|
frameTreeEvents,
|
|
675
671
|
processEvents,
|
|
676
672
|
mainFrameIds,
|
|
677
|
-
timeOriginEvt,
|
|
678
|
-
timings: {
|
|
679
|
-
timeOrigin: 0,
|
|
680
|
-
traceEnd: traceEnd.timing,
|
|
681
|
-
},
|
|
682
|
-
timestamps: {
|
|
683
|
-
timeOrigin: timeOriginEvt.ts,
|
|
684
|
-
traceEnd: traceEnd.timestamp,
|
|
685
|
-
},
|
|
686
|
-
};
|
|
687
|
-
}
|
|
688
|
-
|
|
689
|
-
/**
|
|
690
|
-
* Finds key navigation trace events and computes timings of events in milliseconds since the time
|
|
691
|
-
* origin in addition to the standard microsecond monotonic timestamps.
|
|
692
|
-
* @param {LH.Artifacts.ProcessedTrace} processedTrace
|
|
693
|
-
* @return {LH.Artifacts.ProcessedNavigation}
|
|
694
|
-
*/
|
|
695
|
-
static processNavigation(processedTrace) {
|
|
696
|
-
const {frameEvents, frameTreeEvents, timeOriginEvt, timings, timestamps} = processedTrace;
|
|
697
|
-
|
|
698
|
-
// Compute the key frame timings for the main frame.
|
|
699
|
-
const frameTimings = this.computeNavigationTimingsForFrame(frameEvents, {timeOriginEvt});
|
|
700
|
-
|
|
701
|
-
// Compute FCP for all frames.
|
|
702
|
-
const fcpAllFramesEvt = frameTreeEvents.find(
|
|
703
|
-
e => e.name === 'firstContentfulPaint' && e.ts > timeOriginEvt.ts
|
|
704
|
-
);
|
|
705
|
-
|
|
706
|
-
if (!fcpAllFramesEvt) {
|
|
707
|
-
throw this.createNoFirstContentfulPaintError();
|
|
708
|
-
}
|
|
709
|
-
|
|
710
|
-
// Compute LCP for all frames.
|
|
711
|
-
const lcpAllFramesEvt = this.computeValidLCPAllFrames(frameTreeEvents, timeOriginEvt).lcp;
|
|
712
|
-
|
|
713
|
-
/** @param {number} ts */
|
|
714
|
-
const getTiming = ts => (ts - timeOriginEvt.ts) / 1000;
|
|
715
|
-
/** @param {number=} ts */
|
|
716
|
-
const maybeGetTiming = (ts) => ts === undefined ? undefined : getTiming(ts);
|
|
717
|
-
|
|
718
|
-
return {
|
|
719
673
|
timings: {
|
|
720
|
-
timeOrigin: timings.timeOrigin,
|
|
674
|
+
timeOrigin: frameTimings.timings.timeOrigin,
|
|
721
675
|
firstPaint: frameTimings.timings.firstPaint,
|
|
722
676
|
firstContentfulPaint: frameTimings.timings.firstContentfulPaint,
|
|
723
|
-
firstContentfulPaintAllFrames:
|
|
677
|
+
firstContentfulPaintAllFrames: maybeGetTiming(fcpAllFramesEvt && fcpAllFramesEvt.ts),
|
|
724
678
|
firstMeaningfulPaint: frameTimings.timings.firstMeaningfulPaint,
|
|
725
679
|
largestContentfulPaint: frameTimings.timings.largestContentfulPaint,
|
|
726
680
|
largestContentfulPaintAllFrames: maybeGetTiming(lcpAllFramesEvt && lcpAllFramesEvt.ts),
|
|
681
|
+
traceEnd: traceEnd.timing,
|
|
727
682
|
load: frameTimings.timings.load,
|
|
728
683
|
domContentLoaded: frameTimings.timings.domContentLoaded,
|
|
729
|
-
traceEnd: timings.traceEnd,
|
|
730
684
|
},
|
|
731
685
|
timestamps: {
|
|
732
|
-
timeOrigin: timestamps.timeOrigin,
|
|
686
|
+
timeOrigin: frameTimings.timestamps.timeOrigin,
|
|
733
687
|
firstPaint: frameTimings.timestamps.firstPaint,
|
|
734
688
|
firstContentfulPaint: frameTimings.timestamps.firstContentfulPaint,
|
|
735
|
-
firstContentfulPaintAllFrames: fcpAllFramesEvt.ts,
|
|
689
|
+
firstContentfulPaintAllFrames: fcpAllFramesEvt && fcpAllFramesEvt.ts,
|
|
736
690
|
firstMeaningfulPaint: frameTimings.timestamps.firstMeaningfulPaint,
|
|
737
691
|
largestContentfulPaint: frameTimings.timestamps.largestContentfulPaint,
|
|
738
692
|
largestContentfulPaintAllFrames: lcpAllFramesEvt && lcpAllFramesEvt.ts,
|
|
693
|
+
traceEnd: traceEnd.timestamp,
|
|
739
694
|
load: frameTimings.timestamps.load,
|
|
740
695
|
domContentLoaded: frameTimings.timestamps.domContentLoaded,
|
|
741
|
-
traceEnd: timestamps.traceEnd,
|
|
742
696
|
},
|
|
697
|
+
timeOriginEvt: frameTimings.timeOriginEvt,
|
|
743
698
|
firstPaintEvt: frameTimings.firstPaintEvt,
|
|
744
699
|
firstContentfulPaintEvt: frameTimings.firstContentfulPaintEvt,
|
|
745
700
|
firstContentfulPaintAllFramesEvt: fcpAllFramesEvt,
|
|
@@ -791,21 +746,6 @@ class TraceProcessor {
|
|
|
791
746
|
* @return {LH.TraceEvent}
|
|
792
747
|
*/
|
|
793
748
|
static computeTimeOrigin(traceEventSubsets, method) {
|
|
794
|
-
const lastNavigationStart = () => {
|
|
795
|
-
// Our time origin will be the last frame navigation in the trace
|
|
796
|
-
const frameEvents = traceEventSubsets.frameEvents;
|
|
797
|
-
return frameEvents.filter(this._isNavigationStartOfInterest).pop();
|
|
798
|
-
};
|
|
799
|
-
|
|
800
|
-
const lighthouseMarker = () => {
|
|
801
|
-
const frameEvents = traceEventSubsets.keyEvents;
|
|
802
|
-
return frameEvents.find(
|
|
803
|
-
evt =>
|
|
804
|
-
evt.name === 'clock_sync' &&
|
|
805
|
-
evt.args.sync_id === TraceProcessor.TIMESPAN_MARKER_ID
|
|
806
|
-
);
|
|
807
|
-
};
|
|
808
|
-
|
|
809
749
|
switch (method) {
|
|
810
750
|
case 'firstResourceSendRequest': {
|
|
811
751
|
// Our time origin will be the timestamp of the first request that's sent in the frame.
|
|
@@ -818,20 +758,12 @@ class TraceProcessor {
|
|
|
818
758
|
return fetchStart;
|
|
819
759
|
}
|
|
820
760
|
case 'lastNavigationStart': {
|
|
821
|
-
|
|
761
|
+
// Our time origin will be the last frame navigation in the trace
|
|
762
|
+
const frameEvents = traceEventSubsets.frameEvents;
|
|
763
|
+
const navigationStart = frameEvents.filter(this._isNavigationStartOfInterest).pop();
|
|
822
764
|
if (!navigationStart) throw this.createNoNavstartError();
|
|
823
765
|
return navigationStart;
|
|
824
766
|
}
|
|
825
|
-
case 'lighthouseMarker': {
|
|
826
|
-
const marker = lighthouseMarker();
|
|
827
|
-
if (!marker) throw this.createNoLighthouseMarkerError();
|
|
828
|
-
return marker;
|
|
829
|
-
}
|
|
830
|
-
case 'auto': {
|
|
831
|
-
const marker = lighthouseMarker() || lastNavigationStart();
|
|
832
|
-
if (!marker) throw this.createNoNavstartError();
|
|
833
|
-
return marker;
|
|
834
|
-
}
|
|
835
767
|
}
|
|
836
768
|
}
|
|
837
769
|
|
|
@@ -841,7 +773,7 @@ class TraceProcessor {
|
|
|
841
773
|
* @param {Array<LH.TraceEvent>} frameEvents
|
|
842
774
|
* @param {{timeOriginEvt: LH.TraceEvent}} options
|
|
843
775
|
*/
|
|
844
|
-
static
|
|
776
|
+
static computeKeyTimingsForFrame(frameEvents, options) {
|
|
845
777
|
const {timeOriginEvt} = options;
|
|
846
778
|
|
|
847
779
|
// Find our first paint of this frame
|
|
@@ -852,10 +784,6 @@ class TraceProcessor {
|
|
|
852
784
|
e => e.name === 'firstContentfulPaint' && e.ts > timeOriginEvt.ts
|
|
853
785
|
);
|
|
854
786
|
|
|
855
|
-
if (!firstContentfulPaint) {
|
|
856
|
-
throw this.createNoFirstContentfulPaintError();
|
|
857
|
-
}
|
|
858
|
-
|
|
859
787
|
// fMP will follow at/after the FP
|
|
860
788
|
let firstMeaningfulPaint = frameEvents.find(
|
|
861
789
|
e => e.name === 'firstMeaningfulPaint' && e.ts > timeOriginEvt.ts
|
|
@@ -887,26 +815,24 @@ class TraceProcessor {
|
|
|
887
815
|
|
|
888
816
|
/** @param {{ts: number}=} event */
|
|
889
817
|
const getTimestamp = (event) => event && event.ts;
|
|
890
|
-
/** @type {
|
|
818
|
+
/** @type {TraceTimesWithoutFCPAndTraceEnd} */
|
|
891
819
|
const timestamps = {
|
|
892
820
|
timeOrigin: timeOriginEvt.ts,
|
|
893
821
|
firstPaint: getTimestamp(firstPaint),
|
|
894
|
-
firstContentfulPaint: firstContentfulPaint
|
|
822
|
+
firstContentfulPaint: getTimestamp(firstContentfulPaint),
|
|
895
823
|
firstMeaningfulPaint: getTimestamp(firstMeaningfulPaint),
|
|
896
824
|
largestContentfulPaint: getTimestamp(lcpResult.lcp),
|
|
897
825
|
load: getTimestamp(load),
|
|
898
826
|
domContentLoaded: getTimestamp(domContentLoaded),
|
|
899
827
|
};
|
|
900
828
|
|
|
901
|
-
/** @param {number} ts */
|
|
902
|
-
const getTiming = ts => (ts - timeOriginEvt.ts) / 1000;
|
|
903
829
|
/** @param {number=} ts */
|
|
904
|
-
const maybeGetTiming = (ts) => ts === undefined ? undefined :
|
|
905
|
-
/** @type {
|
|
830
|
+
const maybeGetTiming = (ts) => ts === undefined ? undefined : (ts - timeOriginEvt.ts) / 1000;
|
|
831
|
+
/** @type {TraceTimesWithoutFCPAndTraceEnd} */
|
|
906
832
|
const timings = {
|
|
907
833
|
timeOrigin: 0,
|
|
908
834
|
firstPaint: maybeGetTiming(timestamps.firstPaint),
|
|
909
|
-
firstContentfulPaint:
|
|
835
|
+
firstContentfulPaint: maybeGetTiming(timestamps.firstContentfulPaint),
|
|
910
836
|
firstMeaningfulPaint: maybeGetTiming(timestamps.firstMeaningfulPaint),
|
|
911
837
|
largestContentfulPaint: maybeGetTiming(timestamps.largestContentfulPaint),
|
|
912
838
|
load: maybeGetTiming(timestamps.load),
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* URL shim so we keep our code DRY
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
-
const Util = require('
|
|
12
|
+
const Util = require('../report/html/renderer/util.js');
|
|
13
13
|
|
|
14
14
|
/** @typedef {import('./network-request.js')} NetworkRequest */
|
|
15
15
|
|
|
@@ -202,7 +202,7 @@ class URLShim extends URL {
|
|
|
202
202
|
/**
|
|
203
203
|
* Use `NetworkRequest.isNonNetworkRequest(req)` if working with a request.
|
|
204
204
|
* Note: the `protocol` field from CDP can be 'h2', 'http', (not 'https'!) or it'll be url's scheme.
|
|
205
|
-
* https://source.chromium.org/chromium/chromium/src/+/
|
|
205
|
+
* https://source.chromium.org/chromium/chromium/src/+/master:content/browser/devtools/protocol/network_handler.cc;l=598-611;drc=56d4a9a9deb30be73adcee8737c73bcb2a5ab64f
|
|
206
206
|
* However, a `new URL(href).protocol` has a colon suffix.
|
|
207
207
|
* https://url.spec.whatwg.org/#dom-url-protocol
|
|
208
208
|
* A URL's `scheme` is specced as the `protocol` sans-colon, but isn't exposed on a URL object.
|
|
@@ -215,33 +215,6 @@ class URLShim extends URL {
|
|
|
215
215
|
const urlScheme = protocol.includes(':') ? protocol.slice(0, protocol.indexOf(':')) : protocol;
|
|
216
216
|
return NON_NETWORK_SCHEMES.includes(urlScheme);
|
|
217
217
|
}
|
|
218
|
-
|
|
219
|
-
/**
|
|
220
|
-
* @param {string} src
|
|
221
|
-
* @return {string|undefined}
|
|
222
|
-
*/
|
|
223
|
-
static guessMimeType(src) {
|
|
224
|
-
let url;
|
|
225
|
-
try {
|
|
226
|
-
url = new URL(src);
|
|
227
|
-
} catch {
|
|
228
|
-
return undefined;
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
if (url.protocol === 'data:') {
|
|
232
|
-
const match = url.pathname.match(/image\/(png|jpeg|svg\+xml|webp|gif|avif)(?=;)/);
|
|
233
|
-
if (!match) return undefined;
|
|
234
|
-
return match[0];
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
const match = url.pathname.toLowerCase().match(/\.(png|jpeg|jpg|svg|webp|gif|avif)$/);
|
|
238
|
-
if (!match) return undefined;
|
|
239
|
-
|
|
240
|
-
const ext = match[1];
|
|
241
|
-
if (ext === 'svg') return 'image/svg+xml';
|
|
242
|
-
if (ext === 'jpg') return 'image/jpeg';
|
|
243
|
-
return `image/${ext}`;
|
|
244
|
-
}
|
|
245
218
|
}
|
|
246
219
|
|
|
247
220
|
URLShim.URL = URL;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license Copyright 2018 The Lighthouse Authors. All Rights Reserved.
|
|
3
|
+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
4
|
+
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
|
|
5
|
+
*/
|
|
6
|
+
'use strict';
|
|
7
|
+
|
|
8
|
+
const fs = require('fs');
|
|
9
|
+
|
|
10
|
+
const REPORT_TEMPLATE = fs.readFileSync(__dirname + '/report-template.html', 'utf8');
|
|
11
|
+
const REPORT_JAVASCRIPT = [
|
|
12
|
+
fs.readFileSync(__dirname + '/renderer/util.js', 'utf8'),
|
|
13
|
+
fs.readFileSync(__dirname + '/renderer/dom.js', 'utf8'),
|
|
14
|
+
fs.readFileSync(__dirname + '/renderer/details-renderer.js', 'utf8'),
|
|
15
|
+
fs.readFileSync(__dirname + '/renderer/crc-details-renderer.js', 'utf8'),
|
|
16
|
+
fs.readFileSync(__dirname + '/renderer/snippet-renderer.js', 'utf8'),
|
|
17
|
+
fs.readFileSync(__dirname + '/renderer/element-screenshot-renderer.js', 'utf8'),
|
|
18
|
+
fs.readFileSync(__dirname + '/../../lib/file-namer.js', 'utf8'),
|
|
19
|
+
fs.readFileSync(__dirname + '/renderer/logger.js', 'utf8'),
|
|
20
|
+
fs.readFileSync(__dirname + '/renderer/report-ui-features.js', 'utf8'),
|
|
21
|
+
fs.readFileSync(__dirname + '/renderer/category-renderer.js', 'utf8'),
|
|
22
|
+
fs.readFileSync(__dirname + '/renderer/performance-category-renderer.js', 'utf8'),
|
|
23
|
+
fs.readFileSync(__dirname + '/renderer/pwa-category-renderer.js', 'utf8'),
|
|
24
|
+
fs.readFileSync(__dirname + '/renderer/report-renderer.js', 'utf8'),
|
|
25
|
+
fs.readFileSync(__dirname + '/renderer/i18n.js', 'utf8'),
|
|
26
|
+
fs.readFileSync(__dirname + '/renderer/text-encoding.js', 'utf8'),
|
|
27
|
+
].join(';\n');
|
|
28
|
+
const REPORT_CSS = fs.readFileSync(__dirname + '/report-styles.css', 'utf8');
|
|
29
|
+
const REPORT_TEMPLATES = fs.readFileSync(__dirname + '/templates.html', 'utf8');
|
|
30
|
+
|
|
31
|
+
// Changes to this export interface should be reflected in build/build-dt-report-resources.js
|
|
32
|
+
// and clients/devtools-report-assets.js
|
|
33
|
+
module.exports = {
|
|
34
|
+
REPORT_TEMPLATE,
|
|
35
|
+
REPORT_TEMPLATES,
|
|
36
|
+
REPORT_JAVASCRIPT,
|
|
37
|
+
REPORT_CSS,
|
|
38
|
+
};
|
|
@@ -1,17 +1,21 @@
|
|
|
1
1
|
# Lighthouse HTML Report Renderer
|
|
2
2
|
|
|
3
|
+
[Source on Github](https://github.com/GoogleChrome/lighthouse/tree/master/lighthouse-core/report/html)
|
|
4
|
+
|
|
5
|
+
|
|
3
6
|
## Overview
|
|
4
7
|
|
|
5
|
-
Lighthouse has an
|
|
8
|
+
Lighthouse has an indepedent report renderer that takes the **LHR** (Lighthouse Result object) and creates a DOM tree of the report. It's all done client-side.
|
|
6
9
|
|
|
7
10
|
Example standalone HTML report, delivered by the CLI: [`dbwtest-3.0.3.html`](https://googlechrome.github.io/lighthouse/reports/dbwtest-3.0.3.html) _(View the source! 📖)_
|
|
8
11
|
|
|
9
12
|
### Report Renderer components
|
|
10
13
|
|
|
11
|
-
1. [`report/report-generator.js`](https://github.com/GoogleChrome/lighthouse/blob/master/report/report-generator.js) is the entry point
|
|
14
|
+
1. [`lighthouse-core/report/report-generator.js`](https://github.com/GoogleChrome/lighthouse/blob/master/lighthouse-core/report/report-generator.js) is the current entry point. It compiles together the HTML string with everything required within it.
|
|
12
15
|
- It runs natively in Node.js but can run in the browser after a compile step is applied during our bundling pipeline. That compile step uses a browserify transform that takes any `fs.readFileSync()` calls and replaces them with the stringified file content.
|
|
13
|
-
1. [`report/
|
|
14
|
-
1. [`report/
|
|
16
|
+
1. [`lighthouse-core/report/html/`](https://github.com/GoogleChrome/lighthouse/tree/master/lighthouse-core/report/html) has everything required to create the HTML report.
|
|
17
|
+
1. [`lighthouse-core/report/html/renderer`](https://github.com/GoogleChrome/lighthouse/tree/master/lighthouse-core/report/html/renderer) are all client-side JS files. They transform an LHR object into a report DOM tree. They are all executed within the browser.
|
|
18
|
+
1. [`lighthouse-core/report/html/report-template.html`](https://github.com/GoogleChrome/lighthouse/blob/master/lighthouse-core/report/html/report-template.html) is where the client-side build of the DOM report is typically kicked off ([with these four lines](https://github.com/GoogleChrome/lighthouse/blob/eda3a3e2e271249f261655f9504fd542d6acf0f8/lighthouse-core/report/html/report-template.html#L29-L33)) However, see _Current Uses.._ below for more possibilities.
|
|
15
19
|
|
|
16
20
|
|
|
17
21
|
### Data Hydration
|
|
@@ -19,8 +23,8 @@ Example standalone HTML report, delivered by the CLI: [`dbwtest-3.0.3.html`](htt
|
|
|
19
23
|
|
|
20
24
|
Examples:
|
|
21
25
|
|
|
22
|
-
* [`templates.html`](https://github.com/GoogleChrome/lighthouse/blob/master/report/
|
|
23
|
-
* [`performance-category-renderer.js`](https://github.com/GoogleChrome/lighthouse/blob/master/report/renderer/performance-category-renderer.js)
|
|
26
|
+
* [`templates.html`](https://github.com/GoogleChrome/lighthouse/blob/master/lighthouse-core/report/html/templates.html)
|
|
27
|
+
* [`performance-category-renderer.js`](https://github.com/GoogleChrome/lighthouse/blob/master/lighthouse-core/report/html/renderer/performance-category-renderer.js)
|
|
24
28
|
|
|
25
29
|
### Current uses of report renderer
|
|
26
30
|
|
|
@@ -29,4 +33,4 @@ The renderer was designed to be portable across various environments.
|
|
|
29
33
|
1. _LH Chrome Extension_: It [creates the HTML as the runner finishes up](https://github.com/GoogleChrome/lighthouse/blob/440155cdda377c458c0efce006bc3a69ce2a351c/lighthouse-core/runner.js#L137-L138) and transforms it [into a blob url in the background page](https://github.com/GoogleChrome/lighthouse/blob/440155cdda377c458c0efce006bc3a69ce2a351c/lighthouse-extension/app/src/lighthouse-ext-background.js#L129-L143).
|
|
30
34
|
1. _LH CLI_: It [creates the HTML as the runner finishes up](https://github.com/GoogleChrome/lighthouse/blob/440155cdda377c458c0efce006bc3a69ce2a351c/lighthouse-core/runner.js#L137-L138) and [saves it to disk](https://github.com/GoogleChrome/lighthouse/blob/440155cdda377c458c0efce006bc3a69ce2a351c/lighthouse-cli/printer.js#L71-L92).
|
|
31
35
|
1. _Chrome DevTools Audits Panel_: The `renderer` files are rolled into the Chromium repo, and they execute within the DevTools context. The audits panel [receives the LHR object from a WebWorker](https://github.com/ChromeDevTools/devtools-frontend/blob/aa1532c2f8bdc37c9886255644ed90ad01c61c77/front_end/audits/AuditsProtocolService.js#L27-L35), through a `postMessage` and then runs [the renderer within DevTools UI](https://github.com/ChromeDevTools/devtools-frontend/blob/aa1532c2f8bdc37c9886255644ed90ad01c61c77/front_end/audits/AuditsPanel.js#L123-L157), making a few [simplifications](https://github.com/ChromeDevTools/devtools-frontend/blob/master/front_end/audits/AuditsReportRenderer.js).
|
|
32
|
-
1. _Hosted [Lighthouse Viewer](https://googlechrome.github.io/lighthouse/viewer/)_: It's a webapp that has the renderer (along with some [additional features](https://github.com/GoogleChrome/lighthouse/blob/master/report/renderer/report-ui-features.js)) all compiled into a [`viewer.js`](https://googlechrome.github.io/lighthouse/viewer/src/viewer.js) file. Same [basic approach](https://github.com/GoogleChrome/lighthouse/blob/440155cdda377c458c0efce006bc3a69ce2a351c/lighthouse-viewer/app/src/lighthouse-report-viewer.js#L116-L117) there.
|
|
36
|
+
1. _Hosted [Lighthouse Viewer](https://googlechrome.github.io/lighthouse/viewer/)_: It's a webapp that has the renderer (along with some [additional features](https://github.com/GoogleChrome/lighthouse/blob/master/lighthouse-core/report/html/renderer/report-ui-features.js)) all compiled into a [`viewer.js`](https://googlechrome.github.io/lighthouse/viewer/src/viewer.js) file. Same [basic approach](https://github.com/GoogleChrome/lighthouse/blob/440155cdda377c458c0efce006bc3a69ce2a351c/lighthouse-viewer/app/src/lighthouse-report-viewer.js#L116-L117) there.
|
|
File without changes
|
|
File without changes
|
|
@@ -355,7 +355,7 @@ class DetailsRenderer {
|
|
|
355
355
|
* @return {LH.Audit.Details.OpportunityColumnHeading['subItemsHeading']}
|
|
356
356
|
*/
|
|
357
357
|
_getCanonicalizedsubItemsHeading(subItemsHeading, parentHeading) {
|
|
358
|
-
// Low-friction way to prevent
|
|
358
|
+
// Low-friction way to prevent commiting a falsy key (which is never allowed for
|
|
359
359
|
// a subItemsHeading) from passing in CI.
|
|
360
360
|
if (!subItemsHeading.key) {
|
|
361
361
|
// eslint-disable-next-line no-console
|
|
File without changes
|
|
File without changes
|
|
@@ -99,7 +99,7 @@ class I18n {
|
|
|
99
99
|
}
|
|
100
100
|
|
|
101
101
|
/**
|
|
102
|
-
* Format bytes with a constant number of fractional digits, i.e
|
|
102
|
+
* Format bytes with a constant number of fractional digits, i.e for a granularity of 0.1, 10 becomes '10.0'
|
|
103
103
|
* @param {number} granularity Controls how coarse the displayed value is
|
|
104
104
|
* @return {Intl.NumberFormat}
|
|
105
105
|
*/
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -911,7 +911,7 @@ class DropDown {
|
|
|
911
911
|
/**
|
|
912
912
|
* @param {Array<Node>} allNodes
|
|
913
913
|
* @param {?HTMLElement=} startNode
|
|
914
|
-
* @
|
|
914
|
+
* @returns {HTMLElement}
|
|
915
915
|
*/
|
|
916
916
|
_getNextSelectableNode(allNodes, startNode) {
|
|
917
917
|
const nodes = allNodes.filter(/** @return {node is HTMLElement} */ (node) => {
|
|
@@ -942,7 +942,7 @@ class DropDown {
|
|
|
942
942
|
|
|
943
943
|
/**
|
|
944
944
|
* @param {?HTMLElement=} startEl
|
|
945
|
-
* @
|
|
945
|
+
* @returns {HTMLElement}
|
|
946
946
|
*/
|
|
947
947
|
_getNextMenuItem(startEl) {
|
|
948
948
|
const nodes = Array.from(this._menuEl.childNodes);
|
|
@@ -951,7 +951,7 @@ class DropDown {
|
|
|
951
951
|
|
|
952
952
|
/**
|
|
953
953
|
* @param {?HTMLElement=} startEl
|
|
954
|
-
* @
|
|
954
|
+
* @returns {HTMLElement}
|
|
955
955
|
*/
|
|
956
956
|
_getPreviousMenuItem(startEl) {
|
|
957
957
|
const nodes = Array.from(this._menuEl.childNodes).reverse();
|
|
File without changes
|
|
File without changes
|
|
@@ -375,7 +375,7 @@ class Util {
|
|
|
375
375
|
/**
|
|
376
376
|
* Returns a primary domain for provided hostname (e.g. www.example.com -> example.com).
|
|
377
377
|
* @param {string|URL} url hostname or URL object
|
|
378
|
-
* @
|
|
378
|
+
* @returns {string}
|
|
379
379
|
*/
|
|
380
380
|
static getRootDomain(url) {
|
|
381
381
|
const hostname = Util.createOrReturnURL(url).hostname;
|
|
@@ -581,7 +581,7 @@ Util.UIStrings = {
|
|
|
581
581
|
|
|
582
582
|
/** This label is for a checkbox above a table of items loaded by a web page. The checkbox is used to show or hide third-party (or "3rd-party") resources in the table, where "third-party resources" refers to items loaded by a web page from URLs that aren't controlled by the owner of the web page. */
|
|
583
583
|
thirdPartyResourcesLabel: 'Show 3rd-party resources',
|
|
584
|
-
/** This label is for a button that opens a new tab to a webapp called "Treemap", which is a nested visual representation of a heierarchy of data
|
|
584
|
+
/** This label is for a button that opens a new tab to a webapp called "Treemap", which is a nested visual representation of a heierarchy of data releated to the reports (script bytes and coverage, resource breakdown, etc.) */
|
|
585
585
|
viewTreemapLabel: 'View Treemap',
|
|
586
586
|
|
|
587
587
|
/** Option in a dropdown menu that opens a small, summary report in a print dialog. */
|
|
@@ -596,7 +596,7 @@ Util.UIStrings = {
|
|
|
596
596
|
dropdownSaveJSON: 'Save as JSON',
|
|
597
597
|
/** Option in a dropdown menu that opens the current report in the Lighthouse Viewer Application. */
|
|
598
598
|
dropdownViewer: 'Open in Viewer',
|
|
599
|
-
/** Option in a dropdown menu that saves the current report as a new
|
|
599
|
+
/** Option in a dropdown menu that saves the current report as a new Github Gist. */
|
|
600
600
|
dropdownSaveGist: 'Save as Gist',
|
|
601
601
|
/** Option in a dropdown menu that toggles the themeing of the report between Light(default) and Dark themes. */
|
|
602
602
|
dropdownDarkTheme: 'Toggle Dark Theme',
|
|
@@ -624,7 +624,7 @@ Util.UIStrings = {
|
|
|
624
624
|
/** Label for a row in a table that shows the version of the Axe library used. Example row values: 2.1.0, 3.2.3 */
|
|
625
625
|
runtimeSettingsAxeVersion: 'Axe version',
|
|
626
626
|
|
|
627
|
-
/** Label for button to create an issue against the Lighthouse
|
|
627
|
+
/** Label for button to create an issue against the Lighthouse Github project. */
|
|
628
628
|
footerIssue: 'File an issue',
|
|
629
629
|
|
|
630
630
|
/** Descriptive explanation for emulation setting when no device emulation is set. */
|
|
@@ -645,6 +645,3 @@ if (typeof module !== 'undefined' && module.exports) {
|
|
|
645
645
|
} else {
|
|
646
646
|
self.Util = Util;
|
|
647
647
|
}
|
|
648
|
-
|
|
649
|
-
// TODO(esmodules): export these strings too, then collect-strings will work when this file is esm.
|
|
650
|
-
// export const UIStrings = Util.UIStrings;
|
|
File without changes
|
package/{report/assets/standalone-template.html → lighthouse-core/report/html/report-template.html}
RENAMED
|
@@ -31,10 +31,50 @@ limitations under the License.
|
|
|
31
31
|
|
|
32
32
|
<div id="lh-log"></div>
|
|
33
33
|
|
|
34
|
-
<script>window.__LIGHTHOUSE_JSON__ = %%LIGHTHOUSE_JSON%%;</script>
|
|
35
34
|
<script>%%LIGHTHOUSE_JAVASCRIPT%%
|
|
36
35
|
//# sourceURL=compiled-reportrenderer.js
|
|
37
36
|
</script>
|
|
37
|
+
<script>window.__LIGHTHOUSE_JSON__ = %%LIGHTHOUSE_JSON%%;</script>
|
|
38
38
|
<script>console.log('window.__LIGHTHOUSE_JSON__', __LIGHTHOUSE_JSON__);</script>
|
|
39
|
+
<script>
|
|
40
|
+
function __initLighthouseReport__() {
|
|
41
|
+
const dom = new DOM(document);
|
|
42
|
+
const renderer = new ReportRenderer(dom);
|
|
43
|
+
|
|
44
|
+
const container = document.querySelector('main');
|
|
45
|
+
renderer.renderReport(window.__LIGHTHOUSE_JSON__, container);
|
|
46
|
+
|
|
47
|
+
// Hook in JS features and page-level event listeners after the report
|
|
48
|
+
// is in the document.
|
|
49
|
+
const features = new ReportUIFeatures(dom);
|
|
50
|
+
features.initFeatures(window.__LIGHTHOUSE_JSON__);
|
|
51
|
+
}
|
|
52
|
+
window.addEventListener('DOMContentLoaded', __initLighthouseReport__);
|
|
53
|
+
|
|
54
|
+
document.addEventListener('lh-analytics', e => {
|
|
55
|
+
if (window.ga) {
|
|
56
|
+
ga(e.detail.cmd, e.detail.fields);
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
document.addEventListener('lh-log', e => {
|
|
61
|
+
const logger = new Logger(document.querySelector('#lh-log'));
|
|
62
|
+
|
|
63
|
+
switch (e.detail.cmd) {
|
|
64
|
+
case 'log':
|
|
65
|
+
logger.log(e.detail.msg);
|
|
66
|
+
break;
|
|
67
|
+
case 'warn':
|
|
68
|
+
logger.warn(e.detail.msg);
|
|
69
|
+
break;
|
|
70
|
+
case 'error':
|
|
71
|
+
logger.error(e.detail.msg);
|
|
72
|
+
break;
|
|
73
|
+
case 'hide':
|
|
74
|
+
logger.hide();
|
|
75
|
+
break;
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
</script>
|
|
39
79
|
</body>
|
|
40
80
|
</html>
|
|
File without changes
|
|
@@ -18,7 +18,7 @@ const fs = require('fs');
|
|
|
18
18
|
const path = require('path');
|
|
19
19
|
const URL = require('./lib/url-shim.js');
|
|
20
20
|
const Sentry = require('./lib/sentry.js');
|
|
21
|
-
const generateReport = require('
|
|
21
|
+
const generateReport = require('./report/report-generator.js').generateReport;
|
|
22
22
|
const LHError = require('./lib/lh-error.js');
|
|
23
23
|
|
|
24
24
|
/** @typedef {import('./gather/connections/connection.js')} Connection */
|