lighthouse 11.7.0-dev.20240416 → 11.7.0-dev.20240418

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.
Files changed (101) hide show
  1. package/cli/bin.js +0 -7
  2. package/cli/cli-flags.d.ts +1 -5
  3. package/cli/cli-flags.js +1 -5
  4. package/cli/test/smokehouse/core-tests.js +0 -2
  5. package/core/audits/accessibility/aria-conditional-attr.d.ts +10 -0
  6. package/core/audits/accessibility/aria-conditional-attr.js +43 -0
  7. package/core/audits/accessibility/aria-deprecated-role.d.ts +10 -0
  8. package/core/audits/accessibility/aria-deprecated-role.js +43 -0
  9. package/core/audits/accessibility/aria-prohibited-attr.d.ts +10 -0
  10. package/core/audits/accessibility/aria-prohibited-attr.js +44 -0
  11. package/core/audits/byte-efficiency/render-blocking-resources.js +3 -1
  12. package/core/audits/byte-efficiency/unminified-css.js +2 -2
  13. package/core/audits/byte-efficiency/unused-css-rules.js +3 -1
  14. package/core/audits/font-display.js +2 -2
  15. package/core/audits/resource-summary.d.ts +2 -0
  16. package/core/audits/resource-summary.js +5 -4
  17. package/core/computed/resource-summary.d.ts +10 -12
  18. package/core/computed/resource-summary.js +12 -19
  19. package/core/computed/unused-css.d.ts +3 -1
  20. package/core/computed/unused-css.js +6 -5
  21. package/core/config/config-helpers.js +0 -4
  22. package/core/config/constants.js +0 -1
  23. package/core/config/default-config.js +7 -14
  24. package/core/gather/gatherers/accessibility.js +3 -3
  25. package/core/gather/gatherers/css-usage.d.ts +0 -21
  26. package/core/gather/gatherers/css-usage.js +9 -119
  27. package/core/gather/gatherers/stylesheets.d.ts +26 -0
  28. package/core/gather/gatherers/stylesheets.js +138 -0
  29. package/core/lib/i18n/i18n.d.ts +0 -1
  30. package/core/lib/i18n/i18n.js +0 -2
  31. package/core/runner.js +0 -1
  32. package/dist/report/bundle.esm.js +2 -19
  33. package/dist/report/flow.js +5 -22
  34. package/dist/report/standalone.js +3 -20
  35. package/package.json +3 -3
  36. package/readme.md +2 -2
  37. package/report/assets/styles.css +0 -17
  38. package/report/renderer/components.js +1 -1
  39. package/report/renderer/dom.d.ts +1 -1
  40. package/report/renderer/dom.js +1 -1
  41. package/report/renderer/performance-category-renderer.js +0 -21
  42. package/shared/localization/locales/ar-XB.json +61 -91
  43. package/shared/localization/locales/ar.json +61 -91
  44. package/shared/localization/locales/bg.json +61 -91
  45. package/shared/localization/locales/ca.json +61 -91
  46. package/shared/localization/locales/cs.json +61 -91
  47. package/shared/localization/locales/da.json +61 -91
  48. package/shared/localization/locales/de.json +61 -91
  49. package/shared/localization/locales/el.json +61 -91
  50. package/shared/localization/locales/en-GB.json +61 -91
  51. package/shared/localization/locales/en-US.json +27 -30
  52. package/shared/localization/locales/en-XA.json +61 -91
  53. package/shared/localization/locales/en-XL.json +27 -30
  54. package/shared/localization/locales/es-419.json +61 -91
  55. package/shared/localization/locales/es.json +61 -91
  56. package/shared/localization/locales/fi.json +61 -91
  57. package/shared/localization/locales/fil.json +60 -90
  58. package/shared/localization/locales/fr.json +61 -91
  59. package/shared/localization/locales/he.json +61 -91
  60. package/shared/localization/locales/hi.json +61 -91
  61. package/shared/localization/locales/hr.json +62 -92
  62. package/shared/localization/locales/hu.json +61 -91
  63. package/shared/localization/locales/id.json +61 -91
  64. package/shared/localization/locales/it.json +61 -91
  65. package/shared/localization/locales/ja.json +61 -91
  66. package/shared/localization/locales/ko.json +61 -91
  67. package/shared/localization/locales/lt.json +61 -91
  68. package/shared/localization/locales/lv.json +61 -91
  69. package/shared/localization/locales/nl.json +61 -91
  70. package/shared/localization/locales/no.json +61 -91
  71. package/shared/localization/locales/pl.json +60 -90
  72. package/shared/localization/locales/pt-PT.json +61 -91
  73. package/shared/localization/locales/pt.json +63 -93
  74. package/shared/localization/locales/ro.json +61 -91
  75. package/shared/localization/locales/ru.json +61 -91
  76. package/shared/localization/locales/sk.json +61 -91
  77. package/shared/localization/locales/sl.json +61 -91
  78. package/shared/localization/locales/sr-Latn.json +61 -91
  79. package/shared/localization/locales/sr.json +61 -91
  80. package/shared/localization/locales/sv.json +61 -91
  81. package/shared/localization/locales/ta.json +60 -90
  82. package/shared/localization/locales/te.json +61 -91
  83. package/shared/localization/locales/th.json +61 -91
  84. package/shared/localization/locales/tr.json +61 -91
  85. package/shared/localization/locales/uk.json +61 -91
  86. package/shared/localization/locales/vi.json +60 -90
  87. package/shared/localization/locales/zh-HK.json +61 -91
  88. package/shared/localization/locales/zh-TW.json +60 -90
  89. package/shared/localization/locales/zh.json +61 -91
  90. package/tsconfig.json +0 -1
  91. package/types/artifacts.d.ts +3 -1
  92. package/types/externs.d.ts +0 -2
  93. package/types/lh.d.ts +0 -2
  94. package/types/lhr/settings.d.ts +0 -4
  95. package/core/audits/performance-budget.d.ts +0 -39
  96. package/core/audits/performance-budget.js +0 -154
  97. package/core/audits/timing-budget.d.ts +0 -43
  98. package/core/audits/timing-budget.js +0 -175
  99. package/core/config/budget.d.ts +0 -74
  100. package/core/config/budget.js +0 -340
  101. package/types/lhr/budget.d.ts +0 -60
@@ -13,10 +13,6 @@ import * as i18n from '../lib/i18n/i18n.js';
13
13
  const UIStrings = {
14
14
  /** Title of the Performance category of audits. Equivalent to 'Web performance', this term is inclusive of all web page speed and loading optimization topics. Also used as a label of a score gauge; try to limit to 20 characters. */
15
15
  performanceCategoryTitle: 'Performance',
16
- /** Title of the Budgets section of the Performance Category. 'Budgets' refers to a budget (like a financial budget), but applied to the amount of resources on a page, rather than money. */
17
- budgetsGroupTitle: 'Budgets',
18
- /** Description of the Budgets section of the Performance category. Within this section the budget results are displayed. */
19
- budgetsGroupDescription: 'Performance budgets set standards for the performance of your site.',
20
16
  /** Title of the speed metrics section of the Performance category. Within this section are various speed metrics which quantify the pageload performance into values presented in seconds and milliseconds. */
21
17
  metricGroupTitle: 'Metrics',
22
18
  /** Title of an opportunity sub-section of the Performance category. Within this section are audits with imperative titles that suggest actions the user can take to improve the time of the first initial render of the webpage. */
@@ -136,6 +132,7 @@ const defaultConfig = {
136
132
  {id: 'Scripts', gatherer: 'scripts'},
137
133
  {id: 'SourceMaps', gatherer: 'source-maps'},
138
134
  {id: 'Stacks', gatherer: 'stacks'},
135
+ {id: 'Stylesheets', gatherer: 'stylesheets'},
139
136
  {id: 'TraceElements', gatherer: 'trace-elements'},
140
137
  {id: 'ViewportDimensions', gatherer: 'viewport-dimensions'},
141
138
 
@@ -183,8 +180,6 @@ const defaultConfig = {
183
180
  'network-server-latency',
184
181
  'main-thread-tasks',
185
182
  'metrics',
186
- 'performance-budget',
187
- 'timing-budget',
188
183
  'resource-summary',
189
184
  'third-party-summary',
190
185
  'third-party-facades',
@@ -202,12 +197,15 @@ const defaultConfig = {
202
197
  'accessibility/aria-allowed-attr',
203
198
  'accessibility/aria-allowed-role',
204
199
  'accessibility/aria-command-name',
200
+ 'accessibility/aria-conditional-attr',
201
+ 'accessibility/aria-deprecated-role',
205
202
  'accessibility/aria-dialog-name',
206
203
  'accessibility/aria-hidden-body',
207
204
  'accessibility/aria-hidden-focus',
208
205
  'accessibility/aria-input-field-name',
209
206
  'accessibility/aria-meter-name',
210
207
  'accessibility/aria-progressbar-name',
208
+ 'accessibility/aria-prohibited-attr',
211
209
  'accessibility/aria-required-attr',
212
210
  'accessibility/aria-required-children',
213
211
  'accessibility/aria-required-parent',
@@ -312,10 +310,6 @@ const defaultConfig = {
312
310
  'metrics': {
313
311
  title: str_(UIStrings.metricGroupTitle),
314
312
  },
315
- 'budgets': {
316
- title: str_(UIStrings.budgetsGroupTitle),
317
- description: str_(UIStrings.budgetsGroupDescription),
318
- },
319
313
  'diagnostics': {
320
314
  title: str_(UIStrings.diagnosticsGroupTitle),
321
315
  description: str_(UIStrings.diagnosticsGroupDescription),
@@ -437,10 +431,6 @@ const defaultConfig = {
437
431
  {id: 'work-during-interaction', weight: 0, group: 'diagnostics'},
438
432
  {id: 'bf-cache', weight: 0, group: 'diagnostics'},
439
433
 
440
- // Budget audits.
441
- {id: 'performance-budget', weight: 0, group: 'budgets'},
442
- {id: 'timing-budget', weight: 0, group: 'budgets'},
443
-
444
434
  // Audits past this point contain useful data but are not displayed with other audits.
445
435
  {id: 'network-requests', weight: 0, group: 'hidden'},
446
436
  {id: 'network-rtt', weight: 0, group: 'hidden'},
@@ -468,12 +458,15 @@ const defaultConfig = {
468
458
  {id: 'aria-allowed-attr', weight: 10, group: 'a11y-aria'},
469
459
  {id: 'aria-allowed-role', weight: 1, group: 'a11y-aria'},
470
460
  {id: 'aria-command-name', weight: 7, group: 'a11y-aria'},
461
+ {id: 'aria-conditional-attr', weight: 7, group: 'a11y-aria'},
462
+ {id: 'aria-deprecated-role', weight: 1, group: 'a11y-aria'},
471
463
  {id: 'aria-dialog-name', weight: 7, group: 'a11y-aria'},
472
464
  {id: 'aria-hidden-body', weight: 10, group: 'a11y-aria'},
473
465
  {id: 'aria-hidden-focus', weight: 7, group: 'a11y-aria'},
474
466
  {id: 'aria-input-field-name', weight: 7, group: 'a11y-aria'},
475
467
  {id: 'aria-meter-name', weight: 7, group: 'a11y-aria'},
476
468
  {id: 'aria-progressbar-name', weight: 7, group: 'a11y-aria'},
469
+ {id: 'aria-prohibited-attr', weight: 7, group: 'a11y-aria'},
477
470
  {id: 'aria-required-attr', weight: 10, group: 'a11y-aria'},
478
471
  {id: 'aria-required-children', weight: 10, group: 'a11y-aria'},
479
472
  {id: 'aria-required-parent', weight: 10, group: 'a11y-aria'},
@@ -43,10 +43,10 @@ async function runA11yChecks() {
43
43
  'area-alt': {enabled: false},
44
44
  'aria-allowed-role': {enabled: true},
45
45
  'aria-braille-equivalent': {enabled: false},
46
- 'aria-conditional-attr': {enabled: false},
47
- 'aria-deprecated-role': {enabled: false},
46
+ 'aria-conditional-attr': {enabled: true},
47
+ 'aria-deprecated-role': {enabled: true},
48
48
  'aria-dialog-name': {enabled: true},
49
- 'aria-prohibited-attr': {enabled: false},
49
+ 'aria-prohibited-attr': {enabled: true},
50
50
  'aria-roledescription': {enabled: false},
51
51
  'aria-treeitem-name': {enabled: true},
52
52
  'aria-text': {enabled: true},
@@ -1,26 +1,5 @@
1
1
  export default CSSUsage;
2
2
  declare class CSSUsage extends BaseGatherer {
3
- /** @type {LH.Gatherer.ProtocolSession|undefined} */
4
- _session: LH.Gatherer.ProtocolSession | undefined;
5
- /** @type {Map<string, Promise<LH.Artifacts.CSSStyleSheetInfo|Error>>} */
6
- _sheetPromises: Map<string, Promise<LH.Artifacts.CSSStyleSheetInfo | Error>>;
7
- /**
8
- * Initialize as undefined so we can assert results are fetched.
9
- * @type {LH.Crdp.CSS.RuleUsage[]|undefined}
10
- */
11
- _ruleUsage: LH.Crdp.CSS.RuleUsage[] | undefined;
12
- /**
13
- * @param {LH.Crdp.CSS.StyleSheetAddedEvent} event
14
- */
15
- _onStylesheetAdded(event: LH.Crdp.CSS.StyleSheetAddedEvent): void;
16
- /**
17
- * @param {LH.Gatherer.Context} context
18
- */
19
- startInstrumentation(context: LH.Gatherer.Context): Promise<void>;
20
- /**
21
- * @param {LH.Gatherer.Context} context
22
- */
23
- stopInstrumentation(context: LH.Gatherer.Context): Promise<void>;
24
3
  /**
25
4
  * @param {LH.Gatherer.Context} context
26
5
  * @return {Promise<LH.Artifacts['CSSUsage']>}
@@ -8,145 +8,35 @@
8
8
  * @fileoverview Tracks unused CSS rules.
9
9
  */
10
10
 
11
- import log from 'lighthouse-logger';
12
-
13
11
  import BaseGatherer from '../base-gatherer.js';
14
- import {Sentry} from '../../lib/sentry.js';
15
12
 
16
13
  class CSSUsage extends BaseGatherer {
17
- constructor() {
18
- super();
19
- /** @type {LH.Gatherer.ProtocolSession|undefined} */
20
- this._session = undefined;
21
- /** @type {Map<string, Promise<LH.Artifacts.CSSStyleSheetInfo|Error>>} */
22
- this._sheetPromises = new Map();
23
- /**
24
- * Initialize as undefined so we can assert results are fetched.
25
- * @type {LH.Crdp.CSS.RuleUsage[]|undefined}
26
- */
27
- this._ruleUsage = undefined;
28
- this._onStylesheetAdded = this._onStylesheetAdded.bind(this);
29
- }
30
-
31
14
  /** @type {LH.Gatherer.GathererMeta} */
32
15
  meta = {
33
- supportedModes: ['snapshot', 'timespan', 'navigation'],
16
+ supportedModes: ['snapshot', 'navigation'],
34
17
  };
35
18
 
36
- /**
37
- * @param {LH.Crdp.CSS.StyleSheetAddedEvent} event
38
- */
39
- _onStylesheetAdded(event) {
40
- if (!this._session) throw new Error('Session not initialized');
41
- const styleSheetId = event.header.styleSheetId;
42
- const sheetPromise = this._session.sendCommand('CSS.getStyleSheetText', {styleSheetId})
43
- .then(content => ({
44
- header: event.header,
45
- content: content.text,
46
- }))
47
- .catch(/** @param {Error} err */ (err) => {
48
- log.warn(
49
- 'CSSUsage',
50
- `Error fetching content of stylesheet with URL "${event.header.sourceURL}"`
51
- );
52
- Sentry.captureException(err, {
53
- tags: {
54
- gatherer: 'CSSUsage',
55
- },
56
- extra: {
57
- url: event.header.sourceURL,
58
- },
59
- level: 'error',
60
- });
61
- return err;
62
- });
63
- this._sheetPromises.set(styleSheetId, sheetPromise);
64
- }
65
-
66
19
  /**
67
20
  * @param {LH.Gatherer.Context} context
21
+ * @return {Promise<LH.Artifacts['CSSUsage']>}
68
22
  */
69
- async startInstrumentation(context) {
23
+ async getArtifact(context) {
70
24
  const session = context.driver.defaultSession;
71
- this._session = session;
72
-
73
- // Calling `CSS.enable` will emit events for stylesheets currently on the page.
74
- // We want to ignore these events in navigation mode because they are not relevant to the
75
- // navigation that is about to happen. Adding the event listener *after* calling `CSS.enable`
76
- // ensures that the events for pre-existing stylesheets are ignored.
77
- const isNavigation = context.gatherMode === 'navigation';
78
- if (!isNavigation) {
79
- session.on('CSS.styleSheetAdded', this._onStylesheetAdded);
80
- }
25
+ const executionContext = context.driver.executionContext;
81
26
 
82
27
  await session.sendCommand('DOM.enable');
83
28
  await session.sendCommand('CSS.enable');
84
29
  await session.sendCommand('CSS.startRuleUsageTracking');
85
30
 
86
- if (isNavigation) {
87
- session.on('CSS.styleSheetAdded', this._onStylesheetAdded);
88
- }
89
- }
90
-
91
-
92
- /**
93
- * @param {LH.Gatherer.Context} context
94
- */
95
- async stopInstrumentation(context) {
96
- const session = context.driver.defaultSession;
97
- const coverageResponse = await session.sendCommand('CSS.stopRuleUsageTracking');
98
- this._ruleUsage = coverageResponse.ruleUsage;
99
- session.off('CSS.styleSheetAdded', this._onStylesheetAdded);
100
-
101
- // Ensure we finish fetching all stylesheet contents before disabling the CSS domain
102
- await Promise.all(this._sheetPromises.values());
31
+ // Force style to recompute.
32
+ // Doesn't appear to be necessary in newer versions of Chrome.
33
+ await executionContext.evaluateAsync('getComputedStyle(document.body)');
103
34
 
35
+ const {ruleUsage} = await session.sendCommand('CSS.stopRuleUsageTracking');
104
36
  await session.sendCommand('CSS.disable');
105
37
  await session.sendCommand('DOM.disable');
106
- }
107
-
108
- /**
109
- * @param {LH.Gatherer.Context} context
110
- * @return {Promise<LH.Artifacts['CSSUsage']>}
111
- */
112
- async getArtifact(context) {
113
- const executionContext = context.driver.executionContext;
114
-
115
- if (context.gatherMode === 'snapshot') {
116
- await this.startInstrumentation(context);
117
-
118
- // Force style to recompute.
119
- // Doesn't appear to be necessary in newer versions of Chrome.
120
- await executionContext.evaluateAsync('getComputedStyle(document.body)');
121
-
122
- await this.stopInstrumentation(context);
123
- }
124
-
125
- /** @type {Map<string, LH.Artifacts.CSSStyleSheetInfo>} */
126
- const dedupedStylesheets = new Map();
127
- const sheets = await Promise.all(this._sheetPromises.values());
128
-
129
- for (const sheet of sheets) {
130
- // Erroneous sheets will be reported via sentry and the log.
131
- // We can ignore them here without throwing a fatal error.
132
- if (sheet instanceof Error) {
133
- continue;
134
- }
135
-
136
- // Exclude empty stylesheets.
137
- if (sheet.header.length === 0) {
138
- continue;
139
- }
140
-
141
- dedupedStylesheets.set(sheet.content, sheet);
142
- }
143
-
144
- if (!this._ruleUsage) throw new Error('Issue collecting rule usages');
145
38
 
146
- return {
147
- rules: this._ruleUsage,
148
- stylesheets: Array.from(dedupedStylesheets.values()),
149
- };
39
+ return ruleUsage;
150
40
  }
151
41
  }
152
42
 
@@ -0,0 +1,26 @@
1
+ export default Stylesheets;
2
+ declare class Stylesheets extends BaseGatherer {
3
+ /** @type {LH.Gatherer.ProtocolSession|undefined} */
4
+ _session: LH.Gatherer.ProtocolSession | undefined;
5
+ /** @type {Map<string, Promise<LH.Artifacts.CSSStyleSheetInfo|null>>} */
6
+ _sheetPromises: Map<string, Promise<LH.Artifacts.CSSStyleSheetInfo | null>>;
7
+ /**
8
+ * @param {LH.Crdp.CSS.StyleSheetAddedEvent} event
9
+ */
10
+ _onStylesheetAdded(event: LH.Crdp.CSS.StyleSheetAddedEvent): void;
11
+ /**
12
+ * @param {LH.Gatherer.Context} context
13
+ */
14
+ startInstrumentation(context: LH.Gatherer.Context): Promise<void>;
15
+ /**
16
+ * @param {LH.Gatherer.Context} context
17
+ */
18
+ stopInstrumentation(context: LH.Gatherer.Context): Promise<void>;
19
+ /**
20
+ * @param {LH.Gatherer.Context} context
21
+ * @return {Promise<LH.Artifacts['Stylesheets']>}
22
+ */
23
+ getArtifact(context: LH.Gatherer.Context): Promise<LH.Artifacts['Stylesheets']>;
24
+ }
25
+ import BaseGatherer from '../base-gatherer.js';
26
+ //# sourceMappingURL=stylesheets.d.ts.map
@@ -0,0 +1,138 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2024 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+
7
+ /**
8
+ * @fileoverview Collects all stylesheets and their contents.
9
+ */
10
+
11
+ import log from 'lighthouse-logger';
12
+
13
+ import BaseGatherer from '../base-gatherer.js';
14
+ import {Sentry} from '../../lib/sentry.js';
15
+
16
+ class Stylesheets extends BaseGatherer {
17
+ constructor() {
18
+ super();
19
+ /** @type {LH.Gatherer.ProtocolSession|undefined} */
20
+ this._session = undefined;
21
+ /** @type {Map<string, Promise<LH.Artifacts.CSSStyleSheetInfo|null>>} */
22
+ this._sheetPromises = new Map();
23
+ this._onStylesheetAdded = this._onStylesheetAdded.bind(this);
24
+ }
25
+
26
+ /** @type {LH.Gatherer.GathererMeta} */
27
+ meta = {
28
+ supportedModes: ['snapshot', 'timespan', 'navigation'],
29
+ };
30
+
31
+ /**
32
+ * @param {LH.Crdp.CSS.StyleSheetAddedEvent} event
33
+ */
34
+ _onStylesheetAdded(event) {
35
+ if (!this._session) throw new Error('Session not initialized');
36
+ const styleSheetId = event.header.styleSheetId;
37
+ const sheetPromise = this._session.sendCommand('CSS.getStyleSheetText', {styleSheetId})
38
+ .then(content => ({
39
+ header: event.header,
40
+ content: content.text,
41
+ }))
42
+ .catch(err => {
43
+ log.warn(
44
+ 'Stylesheets',
45
+ `Error fetching content of stylesheet with URL "${event.header.sourceURL}"`
46
+ );
47
+ Sentry.captureException(err, {
48
+ tags: {
49
+ gatherer: 'Stylesheets',
50
+ },
51
+ extra: {
52
+ url: event.header.sourceURL,
53
+ },
54
+ level: 'error',
55
+ });
56
+ return null;
57
+ });
58
+ this._sheetPromises.set(styleSheetId, sheetPromise);
59
+ }
60
+
61
+ /**
62
+ * @param {LH.Gatherer.Context} context
63
+ */
64
+ async startInstrumentation(context) {
65
+ const session = context.driver.defaultSession;
66
+ this._session = session;
67
+
68
+ // Calling `CSS.enable` will emit events for stylesheets currently on the page.
69
+ // We want to ignore these events in navigation mode because they are not relevant to the
70
+ // navigation that is about to happen. Adding the event listener *after* calling `CSS.enable`
71
+ // ensures that the events for pre-existing stylesheets are ignored.
72
+ const isNavigation = context.gatherMode === 'navigation';
73
+ if (!isNavigation) {
74
+ session.on('CSS.styleSheetAdded', this._onStylesheetAdded);
75
+ }
76
+
77
+ await session.sendCommand('DOM.enable');
78
+ await session.sendCommand('CSS.enable');
79
+
80
+ if (isNavigation) {
81
+ session.on('CSS.styleSheetAdded', this._onStylesheetAdded);
82
+ }
83
+ }
84
+
85
+
86
+ /**
87
+ * @param {LH.Gatherer.Context} context
88
+ */
89
+ async stopInstrumentation(context) {
90
+ const session = context.driver.defaultSession;
91
+ session.off('CSS.styleSheetAdded', this._onStylesheetAdded);
92
+
93
+ // Ensure we finish fetching all stylesheet contents before disabling the CSS domain
94
+ await Promise.all(this._sheetPromises.values());
95
+
96
+ await session.sendCommand('CSS.disable');
97
+ await session.sendCommand('DOM.disable');
98
+ }
99
+
100
+ /**
101
+ * @param {LH.Gatherer.Context} context
102
+ * @return {Promise<LH.Artifacts['Stylesheets']>}
103
+ */
104
+ async getArtifact(context) {
105
+ const executionContext = context.driver.executionContext;
106
+
107
+ if (context.gatherMode === 'snapshot') {
108
+ await this.startInstrumentation(context);
109
+
110
+ // Force style to recompute.
111
+ // Doesn't appear to be necessary in newer versions of Chrome.
112
+ await executionContext.evaluateAsync('getComputedStyle(document.body)');
113
+
114
+ await this.stopInstrumentation(context);
115
+ }
116
+
117
+ /** @type {Map<string, LH.Artifacts.CSSStyleSheetInfo>} */
118
+ const dedupedStylesheets = new Map();
119
+ const sheets = await Promise.all(this._sheetPromises.values());
120
+
121
+ for (const sheet of sheets) {
122
+ // Erroneous sheets will be reported via sentry and the log.
123
+ // We can ignore them here without throwing a fatal error.
124
+ if (!sheet) continue;
125
+
126
+ // Exclude empty stylesheets.
127
+ if (sheet.header.length === 0) {
128
+ continue;
129
+ }
130
+
131
+ dedupedStylesheets.set(sheet.content, sheet);
132
+ }
133
+
134
+ return Array.from(dedupedStylesheets.values());
135
+ }
136
+ }
137
+
138
+ export default Stylesheets;
@@ -19,7 +19,6 @@ export namespace UIStrings {
19
19
  const columnRequests: string;
20
20
  const columnName: string;
21
21
  const columnSource: string;
22
- const columnOverBudget: string;
23
22
  const columnElement: string;
24
23
  const columnStartTime: string;
25
24
  const columnDuration: string;
@@ -57,8 +57,6 @@ const UIStrings = {
57
57
  columnName: 'Name',
58
58
  /** Label for a column in a data table; entries will be the locations of JavaScript or CSS code, e.g. the name of a Javascript package or module. */
59
59
  columnSource: 'Source',
60
- /** Label for a column in a data table; entries will be how much a predetermined budget has been exeeded by. Depending on the context, this number could represent an excess in quantity or size of network requests, or, an excess in the duration of time that it takes for the page to load.*/
61
- columnOverBudget: 'Over Budget',
62
60
  /** Label for a column in a data table; entries will be a representation of a DOM element. */
63
61
  columnElement: 'Element',
64
62
  /** Label for a column in a data table; entries will be the number of milliseconds since the page started loading. */
package/core/runner.js CHANGED
@@ -298,7 +298,6 @@ class Runner {
298
298
  auditMode: undefined,
299
299
  output: undefined,
300
300
  channel: undefined,
301
- budgets: undefined,
302
301
  };
303
302
  const normalizedGatherSettings = Object.assign({}, artifacts.settings, overrides);
304
303
  const normalizedAuditSettings = Object.assign({}, settings, overrides);