lighthouse 8.6.0 → 9.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/dist/report/bundle.esm.js +5994 -0
- package/dist/report/flow.js +30 -13
- package/dist/report/standalone.js +41 -35
- package/flow-report/.eslintrc.cjs +2 -0
- package/flow-report/assets/standalone-flow-template.html +3 -2
- package/flow-report/assets/styles.css +108 -31
- package/flow-report/src/app.tsx +18 -18
- package/flow-report/src/common.tsx +28 -15
- package/flow-report/src/header.tsx +12 -13
- package/flow-report/src/help-dialog.tsx +3 -4
- package/flow-report/src/i18n/i18n.tsx +57 -16
- package/flow-report/src/i18n/ui-strings.js +50 -0
- package/flow-report/src/icons.tsx +36 -8
- package/flow-report/src/sidebar/flow.tsx +3 -3
- package/flow-report/src/sidebar/sidebar.tsx +35 -14
- package/flow-report/src/summary/category.tsx +97 -24
- package/flow-report/src/summary/summary.tsx +21 -14
- package/flow-report/src/topbar.tsx +9 -5
- package/flow-report/src/util.ts +33 -26
- package/flow-report/src/wrappers/category-score.tsx +0 -3
- package/flow-report/src/wrappers/markdown.tsx +27 -0
- package/flow-report/src/wrappers/report-renderer.tsx +10 -3
- package/flow-report/src/wrappers/report.tsx +27 -6
- package/flow-report/standalone-flow.tsx +4 -3
- package/flow-report/test/common-test.tsx +32 -17
- package/flow-report/test/flow-report-pptr-test.ts +46 -0
- package/flow-report/test/header-test.tsx +6 -6
- package/flow-report/test/setup/env-setup.ts +1 -1
- package/flow-report/test/sidebar/sidebar-test.tsx +43 -1
- package/flow-report/test/summary/category-test.tsx +120 -24
- package/flow-report/test/summary/summary-test.tsx +1 -1
- package/flow-report/test/topbar-test.tsx +1 -0
- package/flow-report/test/util-test.tsx +32 -11
- package/flow-report/test/wrappers/category-score-test.tsx +87 -0
- package/flow-report/test/wrappers/markdown-test.tsx +29 -0
- package/flow-report/tsconfig.json +1 -0
- package/jest.config.js +4 -2
- package/lighthouse-cli/.eslintrc.cjs +2 -0
- package/lighthouse-cli/cli-flags.js +1 -1
- package/lighthouse-cli/run.js +1 -1
- package/lighthouse-cli/test/smokehouse/frontends/smokehouse-bin.js +0 -0
- package/lighthouse-cli/test/smokehouse/lighthouse-runners/bundle.js +4 -2
- package/lighthouse-cli/test/smokehouse/lighthouse-runners/cli.js +1 -1
- package/lighthouse-cli/test/smokehouse/smokehouse.js +1 -1
- package/lighthouse-core/audits/accessibility/axe-audit.js +7 -1
- package/lighthouse-core/audits/audit.js +1 -1
- package/lighthouse-core/audits/byte-efficiency/byte-efficiency-audit.js +2 -0
- package/lighthouse-core/audits/byte-efficiency/modern-image-formats.js +4 -2
- package/lighthouse-core/audits/byte-efficiency/offscreen-images.js +11 -10
- package/lighthouse-core/audits/byte-efficiency/uses-optimized-images.js +5 -3
- package/lighthouse-core/audits/byte-efficiency/uses-responsive-images-snapshot.js +2 -1
- package/lighthouse-core/audits/byte-efficiency/uses-responsive-images.js +2 -1
- package/lighthouse-core/audits/deprecations.js +33 -11
- package/lighthouse-core/audits/dobetterweb/uses-http2.js +27 -11
- package/lighthouse-core/audits/errors-in-console.js +0 -2
- package/lighthouse-core/audits/image-aspect-ratio.js +5 -5
- package/lighthouse-core/audits/image-size-responsive.js +6 -6
- package/lighthouse-core/audits/installable-manifest.js +5 -3
- package/lighthouse-core/audits/preload-lcp-image.js +7 -5
- package/lighthouse-core/audits/script-treemap-data.js +1 -1
- package/lighthouse-core/audits/unsized-images.js +2 -3
- package/lighthouse-core/computed/image-records.js +4 -3
- package/lighthouse-core/computed/metrics/lantern-total-blocking-time.js +3 -4
- package/lighthouse-core/computed/metrics/tbt-utils.js +57 -0
- package/lighthouse-core/computed/metrics/total-blocking-time.js +3 -53
- package/lighthouse-core/computed/resource-summary.js +1 -1
- package/lighthouse-core/config/config-helpers.js +21 -10
- package/lighthouse-core/config/constants.js +3 -4
- package/lighthouse-core/config/default-config.js +61 -71
- package/lighthouse-core/fraggle-rock/config/config.js +1 -1
- package/lighthouse-core/fraggle-rock/config/default-config.js +4 -5
- package/lighthouse-core/fraggle-rock/gather/base-gatherer.js +6 -1
- package/lighthouse-core/fraggle-rock/gather/session.js +3 -4
- package/lighthouse-core/gather/connections/cri.js +1 -1
- package/lighthouse-core/gather/driver/storage.js +0 -1
- package/lighthouse-core/gather/driver.js +3 -7
- package/lighthouse-core/gather/fetcher.js +4 -7
- package/lighthouse-core/gather/gather-runner.js +29 -6
- package/lighthouse-core/gather/gatherers/accessibility.js +27 -0
- package/lighthouse-core/gather/gatherers/dobetterweb/response-compression.js +1 -0
- package/lighthouse-core/gather/gatherers/image-elements.js +0 -3
- package/lighthouse-core/gather/gatherers/inspector-issues.js +5 -0
- package/lighthouse-core/lib/asset-saver.js +7 -4
- package/lighthouse-core/lib/emulation.js +45 -1
- package/lighthouse-core/lib/i18n/i18n.js +19 -8
- package/lighthouse-core/lib/lh-env.js +2 -0
- package/lighthouse-core/lib/proto-preprocessor.js +14 -2
- package/lighthouse-core/lib/tappable-rects.js +8 -15
- package/lighthouse-core/lib/url-shim.js +1 -1
- package/lighthouse-core/runner.js +1 -1
- package/lighthouse-core/util-commonjs.js +65 -46
- package/package.json +27 -17
- package/readme.md +3 -3
- package/report/.eslintrc.cjs +2 -0
- package/report/README.md +1 -1
- package/report/assets/standalone-template.html +2 -3
- package/report/assets/styles.css +360 -254
- package/report/assets/templates.html +21 -76
- package/report/clients/bundle.js +1 -0
- package/report/clients/standalone.js +6 -15
- package/report/generator/README.md +1 -1
- package/report/renderer/api.js +32 -0
- package/report/renderer/category-renderer.js +59 -19
- package/report/renderer/components.js +59 -110
- package/report/renderer/crc-details-renderer.js +15 -12
- package/report/renderer/dom.js +16 -1
- package/report/renderer/drop-down-menu.js +2 -2
- package/report/renderer/element-screenshot-renderer.js +8 -8
- package/report/renderer/features-util.js +1 -1
- package/report/renderer/open-tab.js +9 -3
- package/report/renderer/performance-category-renderer.js +55 -34
- package/report/renderer/pwa-category-renderer.js +0 -10
- package/report/renderer/report-renderer.js +91 -44
- package/report/renderer/report-ui-features.js +36 -33
- package/report/renderer/swap-locale-feature.js +3 -3
- package/report/renderer/topbar-features.js +53 -48
- package/report/renderer/util.js +66 -46
- package/report/test/clients/bundle-test.js +70 -0
- package/report/test/renderer/category-renderer-test.js +48 -3
- package/report/test/renderer/i18n-test.js +0 -7
- package/report/test/renderer/performance-category-renderer-test.js +51 -14
- package/report/test/renderer/pwa-category-renderer-test.js +6 -6
- package/report/test/renderer/report-renderer-axe-test.js +10 -12
- package/report/test/renderer/report-renderer-test.js +23 -22
- package/report/test/renderer/report-ui-features-test.js +20 -10
- package/report/test/renderer/text-encoding-test.js +1 -1
- package/report/test/renderer/util-test.js +35 -31
- package/report/test-assets/faux-psi-template.html +3 -11
- package/report/test-assets/faux-psi.js +26 -22
- package/report/types/html-renderer.d.ts +2 -0
- package/report/types/report-renderer.d.ts +23 -0
- package/shared/localization/format.js +64 -30
- package/shared/localization/locales/ar-XB.json +72 -75
- package/shared/localization/locales/ar.json +72 -75
- package/shared/localization/locales/bg.json +72 -75
- package/shared/localization/locales/ca.json +72 -75
- package/shared/localization/locales/cs.json +89 -92
- package/shared/localization/locales/da.json +72 -75
- package/shared/localization/locales/de.json +89 -92
- package/shared/localization/locales/el.json +72 -75
- package/shared/localization/locales/en-GB.json +72 -75
- package/shared/localization/locales/en-US.json +75 -75
- package/shared/localization/locales/en-XA.json +72 -75
- package/shared/localization/locales/en-XL.json +75 -75
- package/shared/localization/locales/es-419.json +90 -93
- package/shared/localization/locales/es.json +90 -93
- package/shared/localization/locales/fi.json +72 -75
- package/shared/localization/locales/fil.json +72 -75
- package/shared/localization/locales/fr.json +89 -92
- package/shared/localization/locales/he.json +73 -76
- package/shared/localization/locales/hi.json +72 -75
- package/shared/localization/locales/hr.json +72 -75
- package/shared/localization/locales/hu.json +89 -92
- package/shared/localization/locales/id.json +89 -92
- package/shared/localization/locales/it.json +89 -92
- package/shared/localization/locales/ja.json +89 -92
- package/shared/localization/locales/ko.json +89 -92
- package/shared/localization/locales/lt.json +89 -92
- package/shared/localization/locales/lv.json +95 -98
- package/shared/localization/locales/nl.json +89 -92
- package/shared/localization/locales/no.json +72 -75
- package/shared/localization/locales/pl.json +72 -75
- package/shared/localization/locales/pt-PT.json +72 -75
- package/shared/localization/locales/pt.json +89 -92
- package/shared/localization/locales/ro.json +90 -93
- package/shared/localization/locales/ru.json +89 -92
- package/shared/localization/locales/sk.json +89 -92
- package/shared/localization/locales/sl.json +89 -92
- package/shared/localization/locales/sr-Latn.json +89 -92
- package/shared/localization/locales/sr.json +89 -92
- package/shared/localization/locales/sv.json +72 -75
- package/shared/localization/locales/ta.json +89 -92
- package/shared/localization/locales/te.json +89 -92
- package/shared/localization/locales/th.json +89 -92
- package/shared/localization/locales/tr.json +89 -92
- package/shared/localization/locales/uk.json +92 -95
- package/shared/localization/locales/vi.json +89 -92
- package/shared/localization/locales/zh-HK.json +89 -92
- package/shared/localization/locales/zh-TW.json +89 -92
- package/shared/localization/locales/zh.json +89 -92
- package/shared/localization/locales.js +6 -0
- package/shared/test/localization/format-test.js +45 -9
- package/shared/test/localization/swap-locale-test.js +0 -12
- package/third-party/chromium-synchronization/inspector-issueAdded-types-test.js +19 -11
- package/third-party/chromium-synchronization/installability-errors-test.js +2 -0
- package/third-party/download-content-shell/download-content-shell.js +2 -2
- package/third-party/download-content-shell/utils.js +0 -24
- package/tsconfig-all.json +2 -2
- package/tsconfig.json +0 -1
- package/types/artifacts.d.ts +7 -7
- package/types/enquirer.d.ts +3 -1
- package/types/lhr/audit-details.d.ts +6 -5
- package/types/lhr/flow.d.ts +3 -2
- package/types/lhr/lhr.d.ts +1 -1
- package/types/node.d.ts +5 -5
- package/types/rollup-plugin-postprocess.d.ts +10 -0
- package/changelog.md +0 -5490
- package/lighthouse-core/audits/dobetterweb/appcache-manifest.js +0 -67
- package/lighthouse-core/audits/dobetterweb/external-anchors-use-rel-noopener.js +0 -96
- package/lighthouse-core/audits/redirects-http.js +0 -59
- package/lighthouse-core/gather/gatherers/dobetterweb/appcache.js +0 -34
- package/lighthouse-core/gather/gatherers/http-redirect.js +0 -46
- package/lighthouse-core/lib/i18n/locales/en-US.ctc.json +0 -6699
- package/lighthouse-core/lib/i18n/locales/en-XL.ctc.json +0 -6672
- package/lighthouse-core/scripts/package.json +0 -4
- package/report/clients/psi.js +0 -158
- package/report/test/clients/psi-test.js +0 -143
- package/shared/localization/locales/en-US.ctc.json +0 -6877
- package/shared/localization/locales/en-XL.ctc.json +0 -6852
|
@@ -40,16 +40,17 @@ function getTableRows(tableEl) {
|
|
|
40
40
|
export class ReportUIFeatures {
|
|
41
41
|
/**
|
|
42
42
|
* @param {DOM} dom
|
|
43
|
+
* @param {LH.Renderer.Options} opts
|
|
43
44
|
*/
|
|
44
|
-
constructor(dom) {
|
|
45
|
+
constructor(dom, opts = {}) {
|
|
45
46
|
/** @type {LH.Result} */
|
|
46
47
|
this.json; // eslint-disable-line no-unused-expressions
|
|
47
48
|
/** @type {DOM} */
|
|
48
49
|
this._dom = dom;
|
|
49
|
-
/** @type {Document} */
|
|
50
|
-
this._document = this._dom.document();
|
|
51
|
-
this._topbar = new TopbarFeatures(this, dom);
|
|
52
50
|
|
|
51
|
+
this._opts = opts;
|
|
52
|
+
|
|
53
|
+
this._topbar = opts.omitTopbar ? null : new TopbarFeatures(this, dom);
|
|
53
54
|
this.onMediaQueryChange = this.onMediaQueryChange.bind(this);
|
|
54
55
|
}
|
|
55
56
|
|
|
@@ -61,16 +62,19 @@ export class ReportUIFeatures {
|
|
|
61
62
|
initFeatures(lhr) {
|
|
62
63
|
this.json = lhr;
|
|
63
64
|
|
|
64
|
-
this._topbar
|
|
65
|
-
|
|
65
|
+
if (this._topbar) {
|
|
66
|
+
this._topbar.enable(lhr);
|
|
67
|
+
this._topbar.resetUIState();
|
|
68
|
+
}
|
|
66
69
|
this._setupMediaQueryListeners();
|
|
67
70
|
this._setupThirdPartyFilter();
|
|
68
|
-
this._setupElementScreenshotOverlay(this._dom.
|
|
71
|
+
this._setupElementScreenshotOverlay(this._dom.rootEl);
|
|
69
72
|
|
|
70
73
|
let turnOffTheLights = false;
|
|
71
74
|
// Do not query the system preferences for DevTools - DevTools should only apply dark theme
|
|
72
75
|
// if dark is selected in the settings panel.
|
|
73
|
-
|
|
76
|
+
const disableDarkMode = this._dom.isDevTools() || this._opts.disableAutoDarkModeAndFireworks;
|
|
77
|
+
if (!disableDarkMode && window.matchMedia('(prefers-color-scheme: dark)').matches) {
|
|
74
78
|
turnOffTheLights = true;
|
|
75
79
|
}
|
|
76
80
|
|
|
@@ -94,7 +98,7 @@ export class ReportUIFeatures {
|
|
|
94
98
|
const hasMetricError = lhr.categories.performance && lhr.categories.performance.auditRefs
|
|
95
99
|
.some(audit => Boolean(audit.group === 'metrics' && lhr.audits[audit.id].errorMessage));
|
|
96
100
|
if (hasMetricError) {
|
|
97
|
-
const toggleInputEl = this._dom.find('input.lh-metrics-toggle__input', this.
|
|
101
|
+
const toggleInputEl = this._dom.find('input.lh-metrics-toggle__input', this._dom.rootEl);
|
|
98
102
|
toggleInputEl.checked = true;
|
|
99
103
|
}
|
|
100
104
|
|
|
@@ -109,7 +113,7 @@ export class ReportUIFeatures {
|
|
|
109
113
|
}
|
|
110
114
|
|
|
111
115
|
// Fill in all i18n data.
|
|
112
|
-
for (const node of this._dom.findAll('[data-i18n]', this._dom.
|
|
116
|
+
for (const node of this._dom.findAll('[data-i18n]', this._dom.rootEl)) {
|
|
113
117
|
// These strings are guaranteed to (at least) have a default English string in Util.UIStrings,
|
|
114
118
|
// so this cannot be undefined as long as `report-ui-features.data-i18n` test passes.
|
|
115
119
|
const i18nKey = node.getAttribute('data-i18n');
|
|
@@ -119,18 +123,15 @@ export class ReportUIFeatures {
|
|
|
119
123
|
}
|
|
120
124
|
|
|
121
125
|
/**
|
|
122
|
-
* @param {{
|
|
126
|
+
* @param {{text: string, icon?: string, onClick: () => void}} opts
|
|
123
127
|
*/
|
|
124
128
|
addButton(opts) {
|
|
125
|
-
//
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
const metricsEl = this._document.querySelector('.lh-audit-group--metrics');
|
|
129
|
-
const containerEl = opts.container || metricsEl;
|
|
130
|
-
if (!containerEl) return;
|
|
129
|
+
// Use qSA directly to as we don't want to throw (if this element is missing).
|
|
130
|
+
const metricsEl = this._dom.rootEl.querySelector('.lh-audit-group--metrics');
|
|
131
|
+
if (!metricsEl) return;
|
|
131
132
|
|
|
132
|
-
let buttonsEl =
|
|
133
|
-
if (!buttonsEl) buttonsEl = this._dom.createChildOf(
|
|
133
|
+
let buttonsEl = metricsEl.querySelector('.lh-buttons');
|
|
134
|
+
if (!buttonsEl) buttonsEl = this._dom.createChildOf(metricsEl, 'div', 'lh-buttons');
|
|
134
135
|
|
|
135
136
|
const classes = [
|
|
136
137
|
'lh-button',
|
|
@@ -150,8 +151,10 @@ export class ReportUIFeatures {
|
|
|
150
151
|
* @return {string}
|
|
151
152
|
*/
|
|
152
153
|
getReportHtml() {
|
|
153
|
-
this._topbar
|
|
154
|
-
|
|
154
|
+
if (this._topbar) {
|
|
155
|
+
this._topbar.resetUIState();
|
|
156
|
+
}
|
|
157
|
+
return `<!doctype html><body>${this._dom.rootEl.outerHTML}`;
|
|
155
158
|
}
|
|
156
159
|
|
|
157
160
|
/**
|
|
@@ -163,7 +166,7 @@ export class ReportUIFeatures {
|
|
|
163
166
|
}
|
|
164
167
|
|
|
165
168
|
_enableFireworks() {
|
|
166
|
-
const scoresContainer = this._dom.find('.lh-scores-container', this.
|
|
169
|
+
const scoresContainer = this._dom.find('.lh-scores-container', this._dom.rootEl);
|
|
167
170
|
scoresContainer.classList.add('lh-score100');
|
|
168
171
|
scoresContainer.addEventListener('click', _ => {
|
|
169
172
|
scoresContainer.classList.toggle('lh-fireworks-paused');
|
|
@@ -183,7 +186,9 @@ export class ReportUIFeatures {
|
|
|
183
186
|
* be in their closed state (not opened) and the templates should be unstamped.
|
|
184
187
|
*/
|
|
185
188
|
_resetUIState() {
|
|
186
|
-
this._topbar
|
|
189
|
+
if (this._topbar) {
|
|
190
|
+
this._topbar.resetUIState();
|
|
191
|
+
}
|
|
187
192
|
}
|
|
188
193
|
|
|
189
194
|
/**
|
|
@@ -191,8 +196,7 @@ export class ReportUIFeatures {
|
|
|
191
196
|
* @param {MediaQueryList|MediaQueryListEvent} mql
|
|
192
197
|
*/
|
|
193
198
|
onMediaQueryChange(mql) {
|
|
194
|
-
|
|
195
|
-
root.classList.toggle('lh-narrow', mql.matches);
|
|
199
|
+
this._dom.rootEl.classList.toggle('lh-narrow', mql.matches);
|
|
196
200
|
}
|
|
197
201
|
|
|
198
202
|
_setupThirdPartyFilter() {
|
|
@@ -209,7 +213,7 @@ export class ReportUIFeatures {
|
|
|
209
213
|
];
|
|
210
214
|
|
|
211
215
|
// Get all tables with a text url column.
|
|
212
|
-
const tables = Array.from(this.
|
|
216
|
+
const tables = Array.from(this._dom.rootEl.querySelectorAll('table.lh-table'));
|
|
213
217
|
const tablesWithUrls = tables
|
|
214
218
|
.filter(el =>
|
|
215
219
|
el.querySelector('td.lh-table-column--url, td.lh-table-column--source-location'))
|
|
@@ -256,10 +260,9 @@ export class ReportUIFeatures {
|
|
|
256
260
|
const allThirdParty = thirdPartyRows.length === rowEls.length;
|
|
257
261
|
const allFirstParty = !thirdPartyRows.length;
|
|
258
262
|
|
|
259
|
-
// If all or none of the rows are 3rd party,
|
|
263
|
+
// If all or none of the rows are 3rd party, hide the control.
|
|
260
264
|
if (allThirdParty || allFirstParty) {
|
|
261
|
-
|
|
262
|
-
filterInput.checked = allThirdParty;
|
|
265
|
+
this._dom.find('div.lh-3p-filter', filterTemplate).hidden = true;
|
|
263
266
|
}
|
|
264
267
|
|
|
265
268
|
// Add checkbox to the DOM.
|
|
@@ -276,9 +279,9 @@ export class ReportUIFeatures {
|
|
|
276
279
|
}
|
|
277
280
|
|
|
278
281
|
/**
|
|
279
|
-
* @param {Element}
|
|
282
|
+
* @param {Element} rootEl
|
|
280
283
|
*/
|
|
281
|
-
_setupElementScreenshotOverlay(
|
|
284
|
+
_setupElementScreenshotOverlay(rootEl) {
|
|
282
285
|
const fullPageScreenshot =
|
|
283
286
|
this.json.audits['full-page-screenshot'] &&
|
|
284
287
|
this.json.audits['full-page-screenshot'].details &&
|
|
@@ -288,8 +291,8 @@ export class ReportUIFeatures {
|
|
|
288
291
|
|
|
289
292
|
ElementScreenshotRenderer.installOverlayFeature({
|
|
290
293
|
dom: this._dom,
|
|
291
|
-
|
|
292
|
-
overlayContainerEl:
|
|
294
|
+
rootEl: rootEl,
|
|
295
|
+
overlayContainerEl: rootEl,
|
|
293
296
|
fullPageScreenshot,
|
|
294
297
|
});
|
|
295
298
|
}
|
|
@@ -33,17 +33,17 @@ export class SwapLocaleFeature {
|
|
|
33
33
|
throw new Error('missing icuMessagePaths');
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
this._dom.find('.lh-tools-locale', this._dom.
|
|
36
|
+
this._dom.find('.lh-tools-locale', this._dom.rootEl).classList.remove('lh-hidden');
|
|
37
37
|
|
|
38
38
|
const currentLocale = this._reportUIFeatures.json.configSettings.locale;
|
|
39
39
|
|
|
40
|
-
const containerEl = this._dom.find('.lh-tools-locale__selector-wrapper', this._dom.
|
|
40
|
+
const containerEl = this._dom.find('.lh-tools-locale__selector-wrapper', this._dom.rootEl);
|
|
41
41
|
containerEl.removeAttribute('aria-hidden');
|
|
42
42
|
const selectEl = this._dom.createChildOf(containerEl, 'select', 'lh-locale-selector');
|
|
43
43
|
selectEl.name = 'lh-locale-list';
|
|
44
44
|
selectEl.setAttribute('role', 'menuitem');
|
|
45
45
|
|
|
46
|
-
const toggleEl = this._dom.find('.lh-tool-locale__button', this._dom.
|
|
46
|
+
const toggleEl = this._dom.find('.lh-tool-locale__button', this._dom.rootEl);
|
|
47
47
|
toggleEl.addEventListener('click', () => {
|
|
48
48
|
toggleEl.classList.toggle('lh-active');
|
|
49
49
|
});
|
|
@@ -24,15 +24,13 @@ export class TopbarFeatures {
|
|
|
24
24
|
this.lhr; // eslint-disable-line no-unused-expressions
|
|
25
25
|
this._reportUIFeatures = reportUIFeatures;
|
|
26
26
|
this._dom = dom;
|
|
27
|
-
/** @type {Document} */
|
|
28
|
-
this._document = this._dom.document();
|
|
29
27
|
this._dropDownMenu = new DropDownMenu(this._dom);
|
|
30
28
|
this._copyAttempt = false;
|
|
31
29
|
/** @type {HTMLElement} */
|
|
32
30
|
this.topbarEl; // eslint-disable-line no-unused-expressions
|
|
33
31
|
/** @type {HTMLElement} */
|
|
34
|
-
this.
|
|
35
|
-
/** @type {HTMLElement} */
|
|
32
|
+
this.categoriesEl; // eslint-disable-line no-unused-expressions
|
|
33
|
+
/** @type {HTMLElement?} */
|
|
36
34
|
this.stickyHeaderEl; // eslint-disable-line no-unused-expressions
|
|
37
35
|
/** @type {HTMLElement} */
|
|
38
36
|
this.highlightEl; // eslint-disable-line no-unused-expressions
|
|
@@ -40,7 +38,6 @@ export class TopbarFeatures {
|
|
|
40
38
|
this.onKeyUp = this.onKeyUp.bind(this);
|
|
41
39
|
this.onCopy = this.onCopy.bind(this);
|
|
42
40
|
this.collapseAllDetails = this.collapseAllDetails.bind(this);
|
|
43
|
-
this._updateStickyHeaderOnScroll = this._updateStickyHeaderOnScroll.bind(this);
|
|
44
41
|
}
|
|
45
42
|
|
|
46
43
|
/**
|
|
@@ -48,33 +45,15 @@ export class TopbarFeatures {
|
|
|
48
45
|
*/
|
|
49
46
|
enable(lhr) {
|
|
50
47
|
this.lhr = lhr;
|
|
51
|
-
this.
|
|
52
|
-
this.
|
|
48
|
+
this._dom.rootEl.addEventListener('keyup', this.onKeyUp);
|
|
49
|
+
this._dom.document().addEventListener('copy', this.onCopy);
|
|
53
50
|
this._dropDownMenu.setup(this.onDropDownMenuClick);
|
|
54
51
|
this._setUpCollapseDetailsAfterPrinting();
|
|
55
52
|
|
|
56
|
-
const topbarLogo = this._dom.find('.lh-topbar__logo', this.
|
|
53
|
+
const topbarLogo = this._dom.find('.lh-topbar__logo', this._dom.rootEl);
|
|
57
54
|
topbarLogo.addEventListener('click', () => toggleDarkTheme(this._dom));
|
|
58
55
|
|
|
59
|
-
|
|
60
|
-
if (Object.keys(this.lhr.categories).length >= 2) {
|
|
61
|
-
this._setupStickyHeaderElements();
|
|
62
|
-
const containerEl = this._dom.find('.lh-container', this._document);
|
|
63
|
-
const elToAddScrollListener = this._getScrollParent(containerEl);
|
|
64
|
-
elToAddScrollListener.addEventListener('scroll', this._updateStickyHeaderOnScroll);
|
|
65
|
-
|
|
66
|
-
// Use ResizeObserver where available.
|
|
67
|
-
// TODO: there is an issue with incorrect position numbers and, as a result, performance
|
|
68
|
-
// issues due to layout thrashing.
|
|
69
|
-
// See https://github.com/GoogleChrome/lighthouse/pull/9023/files#r288822287 for details.
|
|
70
|
-
// For now, limit to DevTools.
|
|
71
|
-
if (this._dom.isDevTools()) {
|
|
72
|
-
const resizeObserver = new window.ResizeObserver(this._updateStickyHeaderOnScroll);
|
|
73
|
-
resizeObserver.observe(containerEl);
|
|
74
|
-
} else {
|
|
75
|
-
window.addEventListener('resize', this._updateStickyHeaderOnScroll);
|
|
76
|
-
}
|
|
77
|
-
}
|
|
56
|
+
this._setupStickyHeader();
|
|
78
57
|
}
|
|
79
58
|
|
|
80
59
|
/**
|
|
@@ -112,7 +91,7 @@ export class TopbarFeatures {
|
|
|
112
91
|
try {
|
|
113
92
|
this._reportUIFeatures._saveFile(new Blob([htmlStr], {type: 'text/html'}));
|
|
114
93
|
} catch (e) {
|
|
115
|
-
this._dom.fireEventOn('lh-log', this.
|
|
94
|
+
this._dom.fireEventOn('lh-log', this._dom.document(), {
|
|
116
95
|
cmd: 'error', msg: 'Could not export as HTML. ' + e.message,
|
|
117
96
|
});
|
|
118
97
|
}
|
|
@@ -152,7 +131,7 @@ export class TopbarFeatures {
|
|
|
152
131
|
e.preventDefault();
|
|
153
132
|
e.clipboardData.setData('text/plain', JSON.stringify(this.lhr, null, 2));
|
|
154
133
|
|
|
155
|
-
this._dom.fireEventOn('lh-log', this.
|
|
134
|
+
this._dom.fireEventOn('lh-log', this._dom.document(), {
|
|
156
135
|
cmd: 'log', msg: 'Report JSON copied to clipboard',
|
|
157
136
|
});
|
|
158
137
|
}
|
|
@@ -164,28 +143,28 @@ export class TopbarFeatures {
|
|
|
164
143
|
* Copies the report JSON to the clipboard (if supported by the browser).
|
|
165
144
|
*/
|
|
166
145
|
onCopyButtonClick() {
|
|
167
|
-
this._dom.fireEventOn('lh-analytics', this.
|
|
146
|
+
this._dom.fireEventOn('lh-analytics', this._dom.document(), {
|
|
168
147
|
cmd: 'send',
|
|
169
148
|
fields: {hitType: 'event', eventCategory: 'report', eventAction: 'copy'},
|
|
170
149
|
});
|
|
171
150
|
|
|
172
151
|
try {
|
|
173
|
-
if (this.
|
|
152
|
+
if (this._dom.document().queryCommandSupported('copy')) {
|
|
174
153
|
this._copyAttempt = true;
|
|
175
154
|
|
|
176
155
|
// Note: In Safari 10.0.1, execCommand('copy') returns true if there's
|
|
177
156
|
// a valid text selection on the page. See http://caniuse.com/#feat=clipboard.
|
|
178
|
-
if (!this.
|
|
157
|
+
if (!this._dom.document().execCommand('copy')) {
|
|
179
158
|
this._copyAttempt = false; // Prevent event handler from seeing this as a copy attempt.
|
|
180
159
|
|
|
181
|
-
this._dom.fireEventOn('lh-log', this.
|
|
160
|
+
this._dom.fireEventOn('lh-log', this._dom.document(), {
|
|
182
161
|
cmd: 'warn', msg: 'Your browser does not support copy to clipboard.',
|
|
183
162
|
});
|
|
184
163
|
}
|
|
185
164
|
}
|
|
186
165
|
} catch (e) {
|
|
187
166
|
this._copyAttempt = false;
|
|
188
|
-
this._dom.fireEventOn('lh-log', this.
|
|
167
|
+
this._dom.fireEventOn('lh-log', this._dom.document(), {cmd: 'log', msg: e.message});
|
|
189
168
|
}
|
|
190
169
|
}
|
|
191
170
|
|
|
@@ -206,7 +185,7 @@ export class TopbarFeatures {
|
|
|
206
185
|
* open a `<details>` element.
|
|
207
186
|
*/
|
|
208
187
|
expandAllDetails() {
|
|
209
|
-
const details = this._dom.findAll('.lh-categories details', this.
|
|
188
|
+
const details = this._dom.findAll('.lh-categories details', this._dom.rootEl);
|
|
210
189
|
details.map(detail => detail.open = true);
|
|
211
190
|
}
|
|
212
191
|
|
|
@@ -215,7 +194,7 @@ export class TopbarFeatures {
|
|
|
215
194
|
* open a `<details>` element.
|
|
216
195
|
*/
|
|
217
196
|
collapseAllDetails() {
|
|
218
|
-
const details = this._dom.findAll('.lh-categories details', this.
|
|
197
|
+
const details = this._dom.findAll('.lh-categories details', this._dom.rootEl);
|
|
219
198
|
details.map(detail => detail.open = false);
|
|
220
199
|
}
|
|
221
200
|
|
|
@@ -235,7 +214,7 @@ export class TopbarFeatures {
|
|
|
235
214
|
/**
|
|
236
215
|
* Finds the first scrollable ancestor of `element`. Falls back to the document.
|
|
237
216
|
* @param {Element} element
|
|
238
|
-
* @return {
|
|
217
|
+
* @return {Element | Document}
|
|
239
218
|
*/
|
|
240
219
|
_getScrollParent(element) {
|
|
241
220
|
const {overflowY} = window.getComputedStyle(element);
|
|
@@ -273,24 +252,50 @@ export class TopbarFeatures {
|
|
|
273
252
|
}
|
|
274
253
|
}
|
|
275
254
|
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
this.
|
|
279
|
-
this.
|
|
255
|
+
_setupStickyHeader() {
|
|
256
|
+
// Cache these elements to avoid qSA on each onscroll.
|
|
257
|
+
this.topbarEl = this._dom.find('div.lh-topbar', this._dom.rootEl);
|
|
258
|
+
this.categoriesEl = this._dom.find('div.lh-categories', this._dom.rootEl);
|
|
259
|
+
|
|
260
|
+
// Defer behind rAF to avoid forcing layout.
|
|
261
|
+
window.requestAnimationFrame(() => window.requestAnimationFrame(() => {
|
|
262
|
+
// Only present in the DOM if it'll be used (>=2 categories)
|
|
263
|
+
try {
|
|
264
|
+
this.stickyHeaderEl = this._dom.find('div.lh-sticky-header', this._dom.rootEl);
|
|
265
|
+
} catch {
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
280
268
|
|
|
281
|
-
|
|
282
|
-
|
|
269
|
+
// Highlighter will be absolutely positioned at first gauge, then transformed on scroll.
|
|
270
|
+
this.highlightEl = this._dom.createChildOf(this.stickyHeaderEl, 'div', 'lh-highlighter');
|
|
271
|
+
|
|
272
|
+
// Update sticky header visibility and highlight when page scrolls/resizes.
|
|
273
|
+
const scrollParent = this._getScrollParent(
|
|
274
|
+
this._dom.find('.lh-container', this._dom.rootEl));
|
|
275
|
+
// The 'scroll' handler must be should be on {Element | Document}...
|
|
276
|
+
scrollParent.addEventListener('scroll', () => this._updateStickyHeader());
|
|
277
|
+
// However resizeObserver needs an element, *not* the document.
|
|
278
|
+
const resizeTarget = scrollParent instanceof window.Document
|
|
279
|
+
? document.documentElement
|
|
280
|
+
: scrollParent;
|
|
281
|
+
new window.ResizeObserver(() => this._updateStickyHeader()).observe(resizeTarget);
|
|
282
|
+
}));
|
|
283
283
|
}
|
|
284
284
|
|
|
285
|
-
|
|
286
|
-
|
|
285
|
+
/**
|
|
286
|
+
* Toggle visibility and update highlighter position
|
|
287
|
+
*/
|
|
288
|
+
_updateStickyHeader() {
|
|
289
|
+
if (!this.stickyHeaderEl) return;
|
|
290
|
+
|
|
291
|
+
// Show sticky header when the main 5 gauges clear the topbar.
|
|
287
292
|
const topbarBottom = this.topbarEl.getBoundingClientRect().bottom;
|
|
288
|
-
const
|
|
289
|
-
const showStickyHeader = topbarBottom >=
|
|
293
|
+
const categoriesTop = this.categoriesEl.getBoundingClientRect().top;
|
|
294
|
+
const showStickyHeader = topbarBottom >= categoriesTop;
|
|
290
295
|
|
|
291
296
|
// Highlight mini gauge when section is in view.
|
|
292
297
|
// In view = the last category that starts above the middle of the window.
|
|
293
|
-
const categoryEls = Array.from(this.
|
|
298
|
+
const categoryEls = Array.from(this._dom.rootEl.querySelectorAll('.lh-category'));
|
|
294
299
|
const categoriesAboveTheMiddle =
|
|
295
300
|
categoryEls.filter(el => el.getBoundingClientRect().top - window.innerHeight / 2 < 0);
|
|
296
301
|
const highlightIndex =
|
package/report/renderer/util.js
CHANGED
|
@@ -38,7 +38,11 @@ const listOfTlds = [
|
|
|
38
38
|
'web', 'spb', 'blog', 'jus', 'kiev', 'mil', 'wi', 'qc', 'ca', 'bel', 'on',
|
|
39
39
|
];
|
|
40
40
|
|
|
41
|
-
|
|
41
|
+
class Util {
|
|
42
|
+
/** @type {I18n<typeof UIStrings>} */
|
|
43
|
+
// @ts-expect-error: Is set in report renderer.
|
|
44
|
+
static i18n = null;
|
|
45
|
+
|
|
42
46
|
static get PASS_THRESHOLD() {
|
|
43
47
|
return PASS_THRESHOLD;
|
|
44
48
|
}
|
|
@@ -104,6 +108,23 @@ export class Util {
|
|
|
104
108
|
/** @type {Map<string, Array<LH.ReportResult.AuditRef>>} */
|
|
105
109
|
const relevantAuditToMetricsMap = new Map();
|
|
106
110
|
|
|
111
|
+
// This backcompat converts old LHRs (<9.0.0) to use the new "hidden" group.
|
|
112
|
+
// Old LHRs used "no group" to identify audits that should be hidden in performance instead of the "hidden" group.
|
|
113
|
+
// Newer LHRs use "no group" to identify opportunities and diagnostics whose groups are assigned by details type.
|
|
114
|
+
const [majorVersion] = clone.lighthouseVersion.split('.').map(Number);
|
|
115
|
+
const perfCategory = clone.categories['performance'];
|
|
116
|
+
if (majorVersion < 9 && perfCategory) {
|
|
117
|
+
if (!clone.categoryGroups) clone.categoryGroups = {};
|
|
118
|
+
clone.categoryGroups['hidden'] = {title: ''};
|
|
119
|
+
for (const auditRef of perfCategory.auditRefs) {
|
|
120
|
+
if (!auditRef.group) {
|
|
121
|
+
auditRef.group = 'hidden';
|
|
122
|
+
} else if (['load-opportunities', 'diagnostics'].includes(auditRef.group)) {
|
|
123
|
+
delete auditRef.group;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
107
128
|
for (const category of Object.values(clone.categories)) {
|
|
108
129
|
// Make basic lookup table for relevantAudits
|
|
109
130
|
category.auditRefs.forEach(metricRef => {
|
|
@@ -167,6 +188,8 @@ export class Util {
|
|
|
167
188
|
|
|
168
189
|
/**
|
|
169
190
|
* Convert a score to a rating label.
|
|
191
|
+
* TODO: Return `'error'` for `score === null && !scoreDisplayMode`.
|
|
192
|
+
*
|
|
170
193
|
* @param {number|null} score
|
|
171
194
|
* @param {string=} scoreDisplayMode
|
|
172
195
|
* @return {string}
|
|
@@ -387,43 +410,21 @@ export class Util {
|
|
|
387
410
|
return hostname.split('.').slice(-splitTld.length).join('.');
|
|
388
411
|
}
|
|
389
412
|
|
|
390
|
-
/**
|
|
391
|
-
* @param {LH.Result['configSettings']} settings
|
|
392
|
-
* @return {!Array<{name: string, description: string}>}
|
|
393
|
-
*/
|
|
394
|
-
static getEnvironmentDisplayValues(settings) {
|
|
395
|
-
const emulationDesc = Util.getEmulationDescriptions(settings);
|
|
396
|
-
|
|
397
|
-
return [
|
|
398
|
-
{
|
|
399
|
-
name: Util.i18n.strings.runtimeSettingsDevice,
|
|
400
|
-
description: emulationDesc.deviceEmulation,
|
|
401
|
-
},
|
|
402
|
-
{
|
|
403
|
-
name: Util.i18n.strings.runtimeSettingsNetworkThrottling,
|
|
404
|
-
description: emulationDesc.networkThrottling,
|
|
405
|
-
},
|
|
406
|
-
{
|
|
407
|
-
name: Util.i18n.strings.runtimeSettingsCPUThrottling,
|
|
408
|
-
description: emulationDesc.cpuThrottling,
|
|
409
|
-
},
|
|
410
|
-
];
|
|
411
|
-
}
|
|
412
413
|
|
|
413
414
|
/**
|
|
414
415
|
* @param {LH.Result['configSettings']} settings
|
|
415
|
-
* @return {{deviceEmulation: string, networkThrottling: string, cpuThrottling: string}}
|
|
416
|
+
* @return {!{deviceEmulation: string, networkThrottling: string, cpuThrottling: string, summary: string}}
|
|
416
417
|
*/
|
|
417
418
|
static getEmulationDescriptions(settings) {
|
|
418
419
|
let cpuThrottling;
|
|
419
420
|
let networkThrottling;
|
|
421
|
+
let summary;
|
|
420
422
|
|
|
421
423
|
const throttling = settings.throttling;
|
|
422
424
|
|
|
423
425
|
switch (settings.throttlingMethod) {
|
|
424
426
|
case 'provided':
|
|
425
|
-
cpuThrottling = Util.i18n.strings.throttlingProvided;
|
|
426
|
-
networkThrottling = Util.i18n.strings.throttlingProvided;
|
|
427
|
+
summary = networkThrottling = cpuThrottling = Util.i18n.strings.throttlingProvided;
|
|
427
428
|
break;
|
|
428
429
|
case 'devtools': {
|
|
429
430
|
const {cpuSlowdownMultiplier, requestLatencyMs} = throttling;
|
|
@@ -431,6 +432,13 @@ export class Util {
|
|
|
431
432
|
networkThrottling = `${Util.i18n.formatNumber(requestLatencyMs)}${NBSP}ms HTTP RTT, ` +
|
|
432
433
|
`${Util.i18n.formatNumber(throttling.downloadThroughputKbps)}${NBSP}Kbps down, ` +
|
|
433
434
|
`${Util.i18n.formatNumber(throttling.uploadThroughputKbps)}${NBSP}Kbps up (DevTools)`;
|
|
435
|
+
|
|
436
|
+
const isSlow4G = () => {
|
|
437
|
+
return requestLatencyMs === 150 * 3.75 &&
|
|
438
|
+
throttling.downloadThroughputKbps === 1.6 * 1024 * 0.9 &&
|
|
439
|
+
throttling.uploadThroughputKbps === 750 * 0.9;
|
|
440
|
+
};
|
|
441
|
+
summary = isSlow4G() ? Util.i18n.strings.runtimeSlow4g : Util.i18n.strings.runtimeCustom;
|
|
434
442
|
break;
|
|
435
443
|
}
|
|
436
444
|
case 'simulate': {
|
|
@@ -438,11 +446,15 @@ export class Util {
|
|
|
438
446
|
cpuThrottling = `${Util.i18n.formatNumber(cpuSlowdownMultiplier)}x slowdown (Simulated)`;
|
|
439
447
|
networkThrottling = `${Util.i18n.formatNumber(rttMs)}${NBSP}ms TCP RTT, ` +
|
|
440
448
|
`${Util.i18n.formatNumber(throughputKbps)}${NBSP}Kbps throughput (Simulated)`;
|
|
449
|
+
|
|
450
|
+
const isSlow4G = () => {
|
|
451
|
+
return rttMs === 150 && throughputKbps === 1.6 * 1024;
|
|
452
|
+
};
|
|
453
|
+
summary = isSlow4G() ? Util.i18n.strings.runtimeSlow4g : Util.i18n.strings.runtimeCustom;
|
|
441
454
|
break;
|
|
442
455
|
}
|
|
443
456
|
default:
|
|
444
|
-
cpuThrottling = Util.i18n.strings.runtimeUnknown;
|
|
445
|
-
networkThrottling = Util.i18n.strings.runtimeUnknown;
|
|
457
|
+
summary = cpuThrottling = networkThrottling = Util.i18n.strings.runtimeUnknown;
|
|
446
458
|
}
|
|
447
459
|
|
|
448
460
|
// TODO(paulirish): revise Runtime Settings strings: https://github.com/GoogleChrome/lighthouse/pull/11796
|
|
@@ -455,6 +467,7 @@ export class Util {
|
|
|
455
467
|
deviceEmulation,
|
|
456
468
|
cpuThrottling,
|
|
457
469
|
networkThrottling,
|
|
470
|
+
summary,
|
|
458
471
|
};
|
|
459
472
|
}
|
|
460
473
|
|
|
@@ -524,10 +537,9 @@ export class Util {
|
|
|
524
537
|
let totalWeight = 0;
|
|
525
538
|
for (const auditRef of category.auditRefs) {
|
|
526
539
|
const auditPassed = Util.showAsPassed(auditRef.result);
|
|
527
|
-
const notDisplayed = !auditRef.group && category.id === 'performance';
|
|
528
540
|
|
|
529
541
|
// Don't count the audit if it's manual, N/A, or isn't displayed.
|
|
530
|
-
if (
|
|
542
|
+
if (auditRef.group === 'hidden' ||
|
|
531
543
|
auditRef.result.scoreDisplayMode === 'manual' ||
|
|
532
544
|
auditRef.result.scoreDisplayMode === 'notApplicable') {
|
|
533
545
|
continue;
|
|
@@ -563,14 +575,10 @@ Util.getUniqueSuffix = (() => {
|
|
|
563
575
|
};
|
|
564
576
|
})();
|
|
565
577
|
|
|
566
|
-
/** @type {I18n<typeof Util['UIStrings']>} */
|
|
567
|
-
// @ts-expect-error: Is set in report renderer.
|
|
568
|
-
Util.i18n = null;
|
|
569
|
-
|
|
570
578
|
/**
|
|
571
579
|
* Report-renderer-specific strings.
|
|
572
580
|
*/
|
|
573
|
-
|
|
581
|
+
const UIStrings = {
|
|
574
582
|
/** Disclaimer shown to users below the metric values (First Contentful Paint, Time to Interactive, etc) to warn them that the numbers they see will likely change slightly the next time they run Lighthouse. */
|
|
575
583
|
varianceDisclaimer: 'Values are estimated and may vary. The [performance score is calculated](https://web.dev/performance-scoring/) directly from these metrics.',
|
|
576
584
|
/** Text link pointing to an interactive calculator that explains Lighthouse scoring. The link text should be fairly short. */
|
|
@@ -637,22 +645,12 @@ Util.UIStrings = {
|
|
|
637
645
|
/** Option in a dropdown menu that toggles the themeing of the report between Light(default) and Dark themes. */
|
|
638
646
|
dropdownDarkTheme: 'Toggle Dark Theme',
|
|
639
647
|
|
|
640
|
-
/** Title of the Runtime settings table in a Lighthouse report. Runtime settings are the environment configurations that a specific report used at auditing time. */
|
|
641
|
-
runtimeSettingsTitle: 'Runtime Settings',
|
|
642
|
-
/** Label for a row in a table that shows the URL that was audited during a Lighthouse run. */
|
|
643
|
-
runtimeSettingsUrl: 'URL',
|
|
644
|
-
/** Label for a row in a table that shows the time at which a Lighthouse run was conducted; formatted as a timestamp, e.g. Jan 1, 1970 12:00 AM UTC. */
|
|
645
|
-
runtimeSettingsFetchTime: 'Fetch Time',
|
|
646
648
|
/** Label for a row in a table that describes the kind of device that was emulated for the Lighthouse run. Example values for row elements: 'No Emulation', 'Emulated Desktop', etc. */
|
|
647
649
|
runtimeSettingsDevice: 'Device',
|
|
648
650
|
/** Label for a row in a table that describes the network throttling conditions that were used during a Lighthouse run, if any. */
|
|
649
651
|
runtimeSettingsNetworkThrottling: 'Network throttling',
|
|
650
652
|
/** Label for a row in a table that describes the CPU throttling conditions that were used during a Lighthouse run, if any.*/
|
|
651
653
|
runtimeSettingsCPUThrottling: 'CPU throttling',
|
|
652
|
-
/** Label for a row in a table that shows in what tool Lighthouse is being run (e.g. The lighthouse CLI, Chrome DevTools, Lightrider, WebPageTest, etc). */
|
|
653
|
-
runtimeSettingsChannel: 'Channel',
|
|
654
|
-
/** Label for a row in a table that shows the User Agent that was detected on the Host machine that ran Lighthouse. */
|
|
655
|
-
runtimeSettingsUA: 'User agent (host)',
|
|
656
654
|
/** Label for a row in a table that shows the User Agent that was used to send out all network requests during the Lighthouse run. */
|
|
657
655
|
runtimeSettingsUANetwork: 'User agent (network)',
|
|
658
656
|
/** Label for a row in a table that shows the estimated CPU power of the machine running Lighthouse. Example row values: 532, 1492, 783. */
|
|
@@ -671,9 +669,31 @@ Util.UIStrings = {
|
|
|
671
669
|
runtimeDesktopEmulation: 'Emulated Desktop',
|
|
672
670
|
/** Descriptive explanation for a runtime setting that is set to an unknown value. */
|
|
673
671
|
runtimeUnknown: 'Unknown',
|
|
672
|
+
/** Descriptive label that this analysis run was from a single pageload of a browser (not a summary of hundreds of loads) */
|
|
673
|
+
runtimeSingleLoad: 'Single page load',
|
|
674
|
+
/** Descriptive label that this analysis only considers the initial load of the page, and no interaction beyond when the page had "fully loaded" */
|
|
675
|
+
runtimeAnalysisWindow: 'Initial page load',
|
|
676
|
+
/** Descriptive explanation that this analysis run was from a single pageload of a browser, whereas field data often summarizes hundreds+ of page loads */
|
|
677
|
+
runtimeSingleLoadTooltip: 'This data is taken from a single page load, as opposed to field data summarizing many sessions.', // eslint-disable-line max-len
|
|
674
678
|
|
|
675
679
|
/** Descriptive explanation for environment throttling that was provided by the runtime environment instead of provided by Lighthouse throttling. */
|
|
676
680
|
throttlingProvided: 'Provided by environment',
|
|
681
|
+
/** Label for an interactive control that will reveal or hide a group of content. This control toggles between the text 'Show' and 'Hide'. */
|
|
682
|
+
show: 'Show',
|
|
683
|
+
/** Label for an interactive control that will reveal or hide a group of content. This control toggles between the text 'Show' and 'Hide'. */
|
|
684
|
+
hide: 'Hide',
|
|
685
|
+
/** Label for an interactive control that will reveal or hide a group of content. This control toggles between the text 'Expand view' and 'Collapse view'. */
|
|
686
|
+
expandView: 'Expand view',
|
|
687
|
+
/** Label for an interactive control that will reveal or hide a group of content. This control toggles between the text 'Expand view' and 'Collapse view'. */
|
|
688
|
+
collapseView: 'Collapse view',
|
|
689
|
+
/** Label indicating that Lighthouse throttled the page to emulate a slow 4G network connection. */
|
|
690
|
+
runtimeSlow4g: 'Slow 4G throttling',
|
|
691
|
+
/** Label indicating that Lighthouse throttled the page using custom throttling settings. */
|
|
692
|
+
runtimeCustom: 'Custom throttling',
|
|
677
693
|
};
|
|
694
|
+
Util.UIStrings = UIStrings;
|
|
678
695
|
|
|
679
|
-
export
|
|
696
|
+
export {
|
|
697
|
+
Util,
|
|
698
|
+
UIStrings,
|
|
699
|
+
};
|