lighthouse 12.8.2-dev.20251004 → 12.8.2-dev.20251006

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 (126) hide show
  1. package/cli/test/smokehouse/config/exclusions.js +0 -2
  2. package/core/audits/audit.js +0 -1
  3. package/core/audits/insights/cls-culprits-insight.js +1 -1
  4. package/core/audits/insights/dom-size-insight.js +6 -6
  5. package/core/audits/redirects.js +1 -0
  6. package/core/audits/server-response-time.d.ts +0 -5
  7. package/core/audits/server-response-time.js +12 -26
  8. package/core/computed/metrics/lcp-breakdown.js +1 -0
  9. package/core/config/default-config.js +20 -63
  10. package/core/config/experimental-config.js +1 -26
  11. package/core/config/filters.js +6 -9
  12. package/core/config/lr-desktop-config.js +0 -1
  13. package/core/config/lr-mobile-config.js +0 -1
  14. package/core/gather/gatherers/trace-elements.js +1 -0
  15. package/core/lib/proto-preprocessor.js +5 -22
  16. package/dist/report/bundle.esm.js +10 -49
  17. package/dist/report/flow.js +12 -51
  18. package/dist/report/standalone.js +11 -50
  19. package/flow-report/src/i18n/i18n.d.ts +4 -6
  20. package/package.json +3 -3
  21. package/report/assets/styles.css +0 -39
  22. package/report/renderer/api.js +0 -1
  23. package/report/renderer/category-renderer.js +6 -0
  24. package/report/renderer/components.js +1 -1
  25. package/report/renderer/dom.d.ts +0 -13
  26. package/report/renderer/dom.js +0 -38
  27. package/report/renderer/performance-category-renderer.d.ts +0 -26
  28. package/report/renderer/performance-category-renderer.js +10 -142
  29. package/report/renderer/report-ui-features.d.ts +0 -1
  30. package/report/renderer/report-ui-features.js +3 -13
  31. package/report/renderer/report-utils.d.ts +2 -3
  32. package/report/renderer/report-utils.js +4 -6
  33. package/report/types/report-renderer.d.ts +0 -6
  34. package/shared/localization/locales/ar-XB.json +0 -330
  35. package/shared/localization/locales/ar.json +0 -330
  36. package/shared/localization/locales/bg.json +0 -330
  37. package/shared/localization/locales/ca.json +0 -330
  38. package/shared/localization/locales/cs.json +0 -330
  39. package/shared/localization/locales/da.json +0 -330
  40. package/shared/localization/locales/de.json +0 -330
  41. package/shared/localization/locales/el.json +0 -330
  42. package/shared/localization/locales/en-GB.json +0 -330
  43. package/shared/localization/locales/en-US.json +26 -275
  44. package/shared/localization/locales/en-XA.json +0 -330
  45. package/shared/localization/locales/en-XL.json +26 -275
  46. package/shared/localization/locales/es-419.json +0 -330
  47. package/shared/localization/locales/es.json +0 -330
  48. package/shared/localization/locales/fi.json +0 -330
  49. package/shared/localization/locales/fil.json +0 -330
  50. package/shared/localization/locales/fr.json +0 -330
  51. package/shared/localization/locales/he.json +0 -330
  52. package/shared/localization/locales/hi.json +0 -330
  53. package/shared/localization/locales/hr.json +0 -330
  54. package/shared/localization/locales/hu.json +0 -330
  55. package/shared/localization/locales/id.json +0 -330
  56. package/shared/localization/locales/it.json +0 -330
  57. package/shared/localization/locales/ja.json +0 -330
  58. package/shared/localization/locales/ko.json +0 -330
  59. package/shared/localization/locales/lt.json +0 -330
  60. package/shared/localization/locales/lv.json +0 -330
  61. package/shared/localization/locales/nl.json +0 -330
  62. package/shared/localization/locales/no.json +0 -330
  63. package/shared/localization/locales/pl.json +0 -330
  64. package/shared/localization/locales/pt-PT.json +0 -330
  65. package/shared/localization/locales/pt.json +0 -330
  66. package/shared/localization/locales/ro.json +0 -330
  67. package/shared/localization/locales/ru.json +0 -330
  68. package/shared/localization/locales/sk.json +0 -330
  69. package/shared/localization/locales/sl.json +0 -330
  70. package/shared/localization/locales/sr-Latn.json +0 -330
  71. package/shared/localization/locales/sr.json +0 -330
  72. package/shared/localization/locales/sv.json +0 -330
  73. package/shared/localization/locales/ta.json +0 -330
  74. package/shared/localization/locales/te.json +0 -330
  75. package/shared/localization/locales/th.json +0 -330
  76. package/shared/localization/locales/tr.json +0 -330
  77. package/shared/localization/locales/uk.json +0 -330
  78. package/shared/localization/locales/vi.json +0 -330
  79. package/shared/localization/locales/zh-HK.json +0 -330
  80. package/shared/localization/locales/zh-TW.json +0 -330
  81. package/shared/localization/locales/zh.json +0 -330
  82. package/types/artifacts.d.ts +1 -0
  83. package/types/audit.d.ts +1 -1
  84. package/types/lhr/settings.d.ts +1 -1
  85. package/core/audits/byte-efficiency/duplicated-javascript.d.ts +0 -45
  86. package/core/audits/byte-efficiency/duplicated-javascript.js +0 -223
  87. package/core/audits/byte-efficiency/efficient-animated-content.d.ts +0 -22
  88. package/core/audits/byte-efficiency/efficient-animated-content.js +0 -93
  89. package/core/audits/byte-efficiency/legacy-javascript.d.ts +0 -28
  90. package/core/audits/byte-efficiency/legacy-javascript.js +0 -144
  91. package/core/audits/byte-efficiency/modern-image-formats.d.ts +0 -38
  92. package/core/audits/byte-efficiency/modern-image-formats.js +0 -187
  93. package/core/audits/byte-efficiency/render-blocking-resources.d.ts +0 -53
  94. package/core/audits/byte-efficiency/render-blocking-resources.js +0 -312
  95. package/core/audits/byte-efficiency/uses-long-cache-ttl.d.ts +0 -59
  96. package/core/audits/byte-efficiency/uses-long-cache-ttl.js +0 -293
  97. package/core/audits/byte-efficiency/uses-optimized-images.d.ts +0 -33
  98. package/core/audits/byte-efficiency/uses-optimized-images.js +0 -146
  99. package/core/audits/byte-efficiency/uses-responsive-images-snapshot.d.ts +0 -16
  100. package/core/audits/byte-efficiency/uses-responsive-images-snapshot.js +0 -106
  101. package/core/audits/byte-efficiency/uses-responsive-images.d.ts +0 -44
  102. package/core/audits/byte-efficiency/uses-responsive-images.js +0 -202
  103. package/core/audits/byte-efficiency/uses-text-compression.d.ts +0 -14
  104. package/core/audits/byte-efficiency/uses-text-compression.js +0 -108
  105. package/core/audits/critical-request-chains.d.ts +0 -44
  106. package/core/audits/critical-request-chains.js +0 -221
  107. package/core/audits/dobetterweb/dom-size.d.ts +0 -32
  108. package/core/audits/dobetterweb/dom-size.js +0 -182
  109. package/core/audits/dobetterweb/uses-http2.d.ts +0 -72
  110. package/core/audits/dobetterweb/uses-http2.js +0 -276
  111. package/core/audits/font-display.d.ts +0 -32
  112. package/core/audits/font-display.js +0 -195
  113. package/core/audits/largest-contentful-paint-element.d.ts +0 -34
  114. package/core/audits/largest-contentful-paint-element.js +0 -181
  115. package/core/audits/lcp-lazy-loaded.d.ts +0 -22
  116. package/core/audits/lcp-lazy-loaded.js +0 -115
  117. package/core/audits/prioritize-lcp-image.d.ts +0 -74
  118. package/core/audits/prioritize-lcp-image.js +0 -297
  119. package/core/audits/third-party-summary.d.ts +0 -78
  120. package/core/audits/third-party-summary.js +0 -236
  121. package/core/audits/uses-rel-preconnect.d.ts +0 -37
  122. package/core/audits/uses-rel-preconnect.js +0 -286
  123. package/core/audits/viewport.d.ts +0 -17
  124. package/core/audits/viewport.js +0 -87
  125. package/core/audits/work-during-interaction.d.ts +0 -81
  126. package/core/audits/work-during-interaction.js +0 -287
@@ -1,202 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright 2017 Google LLC
4
- * SPDX-License-Identifier: Apache-2.0
5
- */
6
- /**
7
- * @fileoverview Checks to see if the images used on the page are larger than
8
- * their display sizes. The audit will list all images that are larger than
9
- * their display size with DPR (a 1000px wide image displayed as a
10
- * 500px high-res image on a Retina display is 100% used);
11
- * However, the audit will only fail pages that use images that have waste
12
- * beyond a particular byte threshold.
13
- */
14
-
15
-
16
- import {ByteEfficiencyAudit} from './byte-efficiency-audit.js';
17
- import {NetworkRequest} from '../../lib/network-request.js';
18
- import {ImageRecords} from '../../computed/image-records.js';
19
- import UrlUtils from '../../lib/url-utils.js';
20
- import * as i18n from '../../lib/i18n/i18n.js';
21
-
22
- const UIStrings = {
23
- /** Imperative title of a Lighthouse audit that tells the user to resize images to match the display dimensions. This is displayed in a list of audit titles that Lighthouse generates. */
24
- title: 'Properly size images',
25
- /** Description of a Lighthouse audit that tells the user *why* they need to serve appropriately sized images. This is displayed after a user expands the section to see more. No character length limits. The last sentence starting with 'Learn' becomes link text to additional documentation. */
26
- description:
27
- 'Serve images that are appropriately-sized to save cellular data ' +
28
- 'and improve load time. ' +
29
- '[Learn how to size images](https://developer.chrome.com/docs/lighthouse/performance/uses-responsive-images/).',
30
- };
31
-
32
- const str_ = i18n.createIcuMessageFn(import.meta.url, UIStrings);
33
-
34
- const IGNORE_THRESHOLD_IN_BYTES = 4096;
35
-
36
- // Ignore up to 12KB of waste if an effort was made with breakpoints.
37
- const IGNORE_THRESHOLD_IN_BYTES_BREAKPOINTS_PRESENT = 12288;
38
-
39
- class UsesResponsiveImages extends ByteEfficiencyAudit {
40
- /**
41
- * @return {LH.Audit.Meta}
42
- */
43
- static get meta() {
44
- return {
45
- id: 'uses-responsive-images',
46
- title: str_(UIStrings.title),
47
- description: str_(UIStrings.description),
48
- scoreDisplayMode: ByteEfficiencyAudit.SCORING_MODES.METRIC_SAVINGS,
49
- guidanceLevel: 2,
50
- requiredArtifacts: ['ImageElements', 'ViewportDimensions', 'GatherContext',
51
- 'DevtoolsLog', 'Trace', 'URL', 'SourceMaps'],
52
- };
53
- }
54
-
55
- /**
56
- * @param {LH.Artifacts.ImageElement & {naturalWidth: number, naturalHeight: number}} image
57
- * @param {LH.Artifacts.ViewportDimensions} ViewportDimensions
58
- * @return {{width: number, height: number}};
59
- */
60
- static getDisplayedDimensions(image, ViewportDimensions) {
61
- if (image.displayedWidth && image.displayedHeight) {
62
- return {
63
- width: image.displayedWidth * ViewportDimensions.devicePixelRatio,
64
- height: image.displayedHeight * ViewportDimensions.devicePixelRatio,
65
- };
66
- }
67
-
68
- // If the image has 0 dimensions, it's probably hidden/offscreen, so we'll be as forgiving as possible
69
- // and assume it's the size of two viewports. See https://github.com/GoogleChrome/lighthouse/issues/7236
70
- const viewportWidth = ViewportDimensions.innerWidth;
71
- const viewportHeight = ViewportDimensions.innerHeight * 2;
72
- const imageAspectRatio = image.naturalWidth / image.naturalHeight;
73
- const viewportAspectRatio = viewportWidth / viewportHeight;
74
- let usedViewportWidth = viewportWidth;
75
- let usedViewportHeight = viewportHeight;
76
- if (imageAspectRatio > viewportAspectRatio) {
77
- usedViewportHeight = viewportWidth / imageAspectRatio;
78
- } else {
79
- usedViewportWidth = viewportHeight * imageAspectRatio;
80
- }
81
-
82
- return {
83
- width: usedViewportWidth * ViewportDimensions.devicePixelRatio,
84
- height: usedViewportHeight * ViewportDimensions.devicePixelRatio,
85
- };
86
- }
87
-
88
- /**
89
- * @param {LH.Artifacts.ImageElement & {naturalWidth: number, naturalHeight: number}} image
90
- * @param {LH.Artifacts.ViewportDimensions} ViewportDimensions
91
- * @param {Array<LH.Artifacts.NetworkRequest>} networkRecords
92
- * @return {null|LH.Audit.ByteEfficiencyItem};
93
- */
94
- static computeWaste(image, ViewportDimensions, networkRecords) {
95
- const networkRecord = networkRecords.find(record => record.url === image.src);
96
- // Nothing can be done without network info, ignore images without resource size information.
97
- if (!networkRecord) {
98
- return null;
99
- }
100
-
101
- const displayed = this.getDisplayedDimensions(image, ViewportDimensions);
102
- const usedPixels = displayed.width * displayed.height;
103
-
104
- const url = UrlUtils.elideDataURI(image.src);
105
- const actualPixels = image.naturalWidth * image.naturalHeight;
106
- const wastedRatio = 1 - (usedPixels / actualPixels);
107
- const totalBytes = NetworkRequest.getResourceSizeOnNetwork(networkRecord);
108
- const wastedBytes = Math.round(totalBytes * wastedRatio);
109
-
110
- return {
111
- node: ByteEfficiencyAudit.makeNodeItem(image.node),
112
- url,
113
- totalBytes,
114
- wastedBytes,
115
- wastedPercent: 100 * wastedRatio,
116
- };
117
- }
118
-
119
-
120
- /**
121
- * @param {LH.Artifacts.ImageElement} image
122
- * @return {number};
123
- */
124
- static determineAllowableWaste(image) {
125
- if (image.srcset || image.isPicture) {
126
- return IGNORE_THRESHOLD_IN_BYTES_BREAKPOINTS_PRESENT;
127
- }
128
- return IGNORE_THRESHOLD_IN_BYTES;
129
- }
130
-
131
- /**
132
- * @param {LH.Artifacts} artifacts
133
- * @param {Array<LH.Artifacts.NetworkRequest>} networkRecords
134
- * @param {LH.Audit.Context} context
135
- * @return {Promise<import('./byte-efficiency-audit.js').ByteEfficiencyProduct>}
136
- */
137
- static async audit_(artifacts, networkRecords, context) {
138
- const images = await ImageRecords.request({
139
- ImageElements: artifacts.ImageElements,
140
- networkRecords,
141
- }, context);
142
- const ViewportDimensions = artifacts.ViewportDimensions;
143
- /** @type {Map<string, LH.Audit.ByteEfficiencyItem>} */
144
- const resultsMap = new Map();
145
- /** @type {Array<string>} */
146
- const passedImageList = [];
147
- for (const image of images) {
148
- // Give SVG a free pass because creating a "responsive" SVG is of questionable value.
149
- // Ignore CSS images because it's difficult to determine what is a spritesheet,
150
- // and the reward-to-effort ratio for responsive CSS images is quite low https://css-tricks.com/responsive-images-css/.
151
- if (image.mimeType === 'image/svg+xml' || image.isCss) {
152
- continue;
153
- }
154
-
155
- // Skip if we couldn't collect natural image size information.
156
- if (!image.naturalDimensions) continue;
157
- const naturalHeight = image.naturalDimensions.height;
158
- const naturalWidth = image.naturalDimensions.width;
159
- // If naturalHeight or naturalWidth are falsy, information is not valid, skip.
160
- if (!naturalWidth || !naturalHeight) continue;
161
- const processed =
162
- UsesResponsiveImages.computeWaste(
163
- {...image, naturalHeight, naturalWidth},
164
- ViewportDimensions, networkRecords
165
- );
166
- if (!processed) continue;
167
-
168
- // Verify the image wastes more than the minimum.
169
- const exceedsAllowableWaste = processed.wastedBytes > this.determineAllowableWaste(image);
170
-
171
- const existing = resultsMap.get(processed.url);
172
- // Don't warn about an image that was later used appropriately, or wastes a trivial amount of data.
173
- if (exceedsAllowableWaste && !passedImageList.includes(processed.url)) {
174
- if ((!existing || existing.wastedBytes > processed.wastedBytes)) {
175
- resultsMap.set(processed.url, processed);
176
- }
177
- } else {
178
- // Ensure this url passes for future tests.
179
- resultsMap.delete(processed.url);
180
- passedImageList.push(processed.url);
181
- }
182
- }
183
-
184
- const items = Array.from(resultsMap.values());
185
-
186
- /** @type {LH.Audit.Details.Opportunity['headings']} */
187
- const headings = [
188
- {key: 'node', valueType: 'node', label: ''},
189
- {key: 'url', valueType: 'url', label: str_(i18n.UIStrings.columnURL)},
190
- {key: 'totalBytes', valueType: 'bytes', label: str_(i18n.UIStrings.columnResourceSize)},
191
- {key: 'wastedBytes', valueType: 'bytes', label: str_(i18n.UIStrings.columnWastedBytes)},
192
- ];
193
-
194
- return {
195
- items,
196
- headings,
197
- };
198
- }
199
- }
200
-
201
- export default UsesResponsiveImages;
202
- export {UIStrings, str_};
@@ -1,14 +0,0 @@
1
- export default ResponsesAreCompressed;
2
- declare class ResponsesAreCompressed extends ByteEfficiencyAudit {
3
- /**
4
- * @param {LH.Artifacts} artifacts
5
- * @return {import('./byte-efficiency-audit.js').ByteEfficiencyProduct}
6
- */
7
- static audit_(artifacts: LH.Artifacts): import("./byte-efficiency-audit.js").ByteEfficiencyProduct;
8
- }
9
- export namespace UIStrings {
10
- let title: string;
11
- let description: string;
12
- }
13
- import { ByteEfficiencyAudit } from './byte-efficiency-audit.js';
14
- //# sourceMappingURL=uses-text-compression.d.ts.map
@@ -1,108 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright 2017 Google LLC
4
- * SPDX-License-Identifier: Apache-2.0
5
- */
6
- /*
7
- * @fileoverview Audit a page to ensure that resources loaded with
8
- * gzip/br/deflate compression.
9
- */
10
-
11
-
12
- import {ByteEfficiencyAudit} from './byte-efficiency-audit.js';
13
- import UrlUtils from '../../lib/url-utils.js';
14
- import * as i18n from '../../lib/i18n/i18n.js';
15
-
16
- const UIStrings = {
17
- /** Imperative title of a Lighthouse audit that tells the user to enable text compression (like gzip) in order to enhance the performance of a page. This is displayed in a list of audit titles that Lighthouse generates. */
18
- title: 'Enable text compression',
19
- /** Description of a Lighthouse audit that tells the user *why* their text-based resources should be served with compression (like gzip). This is displayed after a user expands the section to see more. No character length limits. The last sentence starting with 'Learn' becomes link text to additional documentation. */
20
- description: 'Text-based resources should be served with compression (gzip, deflate or' +
21
- ' brotli) to minimize total network bytes.' +
22
- ' [Learn more about text compression](https://developer.chrome.com/docs/lighthouse/performance/uses-text-compression/).',
23
- };
24
-
25
- const str_ = i18n.createIcuMessageFn(import.meta.url, UIStrings);
26
-
27
- const IGNORE_THRESHOLD_IN_BYTES = 1400;
28
- const IGNORE_THRESHOLD_IN_PERCENT = 0.1;
29
-
30
- class ResponsesAreCompressed extends ByteEfficiencyAudit {
31
- /**
32
- * @return {LH.Audit.Meta}
33
- */
34
- static get meta() {
35
- return {
36
- id: 'uses-text-compression',
37
- title: str_(UIStrings.title),
38
- description: str_(UIStrings.description),
39
- scoreDisplayMode: ByteEfficiencyAudit.SCORING_MODES.METRIC_SAVINGS,
40
- guidanceLevel: 3,
41
- requiredArtifacts: ['ResponseCompression', 'GatherContext', 'DevtoolsLog', 'Trace', 'URL',
42
- 'SourceMaps'],
43
- };
44
- }
45
-
46
- /**
47
- * @param {LH.Artifacts} artifacts
48
- * @return {import('./byte-efficiency-audit.js').ByteEfficiencyProduct}
49
- */
50
- static audit_(artifacts) {
51
- const uncompressedResponses = artifacts.ResponseCompression;
52
-
53
- /** @type {Array<LH.Audit.ByteEfficiencyItem>} */
54
- const items = [];
55
- uncompressedResponses.forEach(record => {
56
- // Ignore invalid GZIP size values (undefined, NaN, 0, -n, etc)
57
- if (!record.gzipSize || record.gzipSize < 0) return;
58
-
59
- const originalSize = record.resourceSize;
60
- const gzipSize = record.gzipSize;
61
- const gzipSavings = originalSize - gzipSize;
62
-
63
- // Not every resource is smaller when compressed.
64
- if (record.transferSize < gzipSize) {
65
- return;
66
- }
67
-
68
- // If savings is small, let's be generous and not surface the minor savings.
69
- if (gzipSavings < IGNORE_THRESHOLD_IN_BYTES) {
70
- return;
71
- }
72
-
73
- // Require at least 20kb of savings ... or some percentage of total resource size.
74
- if (gzipSavings < 20_000 && 1 - gzipSize / originalSize < IGNORE_THRESHOLD_IN_PERCENT) {
75
- return;
76
- }
77
-
78
- // remove duplicates
79
- const url = UrlUtils.elideDataURI(record.url);
80
- const isDuplicate = items.find(item => item.url === url &&
81
- item.totalBytes === record.resourceSize);
82
- if (isDuplicate) {
83
- return;
84
- }
85
-
86
- items.push({
87
- url,
88
- totalBytes: originalSize,
89
- wastedBytes: gzipSavings,
90
- });
91
- });
92
-
93
- /** @type {LH.Audit.Details.Opportunity['headings']} */
94
- const headings = [
95
- {key: 'url', valueType: 'url', label: str_(i18n.UIStrings.columnURL)},
96
- {key: 'totalBytes', valueType: 'bytes', label: str_(i18n.UIStrings.columnTransferSize)},
97
- {key: 'wastedBytes', valueType: 'bytes', label: str_(i18n.UIStrings.columnWastedBytes)},
98
- ];
99
-
100
- return {
101
- items,
102
- headings,
103
- };
104
- }
105
- }
106
-
107
- export default ResponsesAreCompressed;
108
- export {UIStrings};
@@ -1,44 +0,0 @@
1
- export default CriticalRequestChains;
2
- declare class CriticalRequestChains extends Audit {
3
- /** @typedef {{depth: number, id: string, chainDuration: number, chainTransferSize: number, node: LH.Artifacts.CriticalRequestNode[string]}} CrcNodeInfo */
4
- /**
5
- * @param {LH.Artifacts.CriticalRequestNode} tree
6
- * @param {function(CrcNodeInfo): void} cb
7
- */
8
- static _traverse(tree: LH.Artifacts.CriticalRequestNode, cb: (arg0: {
9
- depth: number;
10
- id: string;
11
- chainDuration: number;
12
- chainTransferSize: number;
13
- node: LH.Artifacts.CriticalRequestNode[string];
14
- }) => void): void;
15
- /**
16
- * Get stats about the longest initiator chain (as determined by time duration)
17
- * @param {LH.Artifacts.CriticalRequestNode} tree
18
- * @return {{duration: number, length: number, transferSize: number}}
19
- */
20
- static _getLongestChain(tree: LH.Artifacts.CriticalRequestNode): {
21
- duration: number;
22
- length: number;
23
- transferSize: number;
24
- };
25
- /**
26
- * @param {LH.Artifacts.CriticalRequestNode} tree
27
- * @return {LH.Audit.Details.SimpleCriticalRequestNode}
28
- */
29
- static flattenRequests(tree: LH.Artifacts.CriticalRequestNode): LH.Audit.Details.SimpleCriticalRequestNode;
30
- /**
31
- * Audits the page to give a score for First Meaningful Paint.
32
- * @param {LH.Artifacts} artifacts The artifacts from the gather phase.
33
- * @param {LH.Audit.Context} context
34
- * @return {Promise<LH.Audit.Product>}
35
- */
36
- static audit(artifacts: LH.Artifacts, context: LH.Audit.Context): Promise<LH.Audit.Product>;
37
- }
38
- export namespace UIStrings {
39
- let title: string;
40
- let description: string;
41
- let displayValue: string;
42
- }
43
- import { Audit } from './audit.js';
44
- //# sourceMappingURL=critical-request-chains.d.ts.map
@@ -1,221 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright 2016 Google LLC
4
- * SPDX-License-Identifier: Apache-2.0
5
- */
6
-
7
- import {Audit} from './audit.js';
8
- import * as i18n from '../lib/i18n/i18n.js';
9
- import {CriticalRequestChains as ComputedChains} from '../computed/critical-request-chains.js';
10
-
11
- const UIStrings = {
12
- /** Imperative title of a Lighthouse audit that tells the user to reduce the depth of critical network requests to enhance initial load of a page. Critical request chains are series of dependent network requests that are important for page rendering. For example, here's a 4-request-deep chain: The biglogo.jpg image is required, but is requested via the styles.css style code, which is requested by the initialize.js javascript, which is requested by the page's HTML. This is displayed in a list of audit titles that Lighthouse generates. */
13
- title: 'Avoid chaining critical requests',
14
- /** Description of a Lighthouse audit that tells the user *why* they should reduce the depth of critical network requests to enhance initial load of a page . This is displayed after a user expands the section to see more. No character length limits. The last sentence starting with 'Learn' becomes link text to additional documentation. */
15
- description: 'The Critical Request Chains below show you what resources are ' +
16
- 'loaded with a high priority. Consider reducing ' +
17
- 'the length of chains, reducing the download size of resources, or ' +
18
- 'deferring the download of unnecessary resources to improve page load. ' +
19
- '[Learn how to avoid chaining critical requests](https://developer.chrome.com/docs/lighthouse/performance/critical-request-chains/).',
20
- /** [ICU Syntax] Label for an audit identifying the number of sequences of dependent network requests used to load the page. */
21
- displayValue: `{itemCount, plural,
22
- =1 {1 chain found}
23
- other {# chains found}
24
- }`,
25
- };
26
-
27
- const str_ = i18n.createIcuMessageFn(import.meta.url, UIStrings);
28
-
29
- class CriticalRequestChains extends Audit {
30
- /**
31
- * @return {LH.Audit.Meta}
32
- */
33
- static get meta() {
34
- return {
35
- id: 'critical-request-chains',
36
- title: str_(UIStrings.title),
37
- description: str_(UIStrings.description),
38
- scoreDisplayMode: Audit.SCORING_MODES.INFORMATIVE,
39
- supportedModes: ['navigation'],
40
- guidanceLevel: 1,
41
- requiredArtifacts: ['Trace', 'DevtoolsLog', 'URL', 'SourceMaps'],
42
- };
43
- }
44
-
45
- /** @typedef {{depth: number, id: string, chainDuration: number, chainTransferSize: number, node: LH.Artifacts.CriticalRequestNode[string]}} CrcNodeInfo */
46
-
47
- /**
48
- * @param {LH.Artifacts.CriticalRequestNode} tree
49
- * @param {function(CrcNodeInfo): void} cb
50
- */
51
- static _traverse(tree, cb) {
52
- /**
53
- * @param {LH.Artifacts.CriticalRequestNode} node
54
- * @param {number} depth
55
- * @param {number=} networkRequestTime
56
- * @param {number=} transferSize
57
- */
58
- function walk(node, depth, networkRequestTime, transferSize = 0) {
59
- const children = Object.keys(node);
60
- if (children.length === 0) {
61
- return;
62
- }
63
- children.forEach(id => {
64
- const child = node[id];
65
- if (!networkRequestTime) {
66
- networkRequestTime = child.request.networkRequestTime;
67
- }
68
-
69
- // Call the callback with the info for this child.
70
- cb({
71
- depth,
72
- id,
73
- node: child,
74
- chainDuration: child.request.networkEndTime - networkRequestTime,
75
- chainTransferSize: transferSize + child.request.transferSize,
76
- });
77
-
78
- // Carry on walking.
79
- if (child.children) {
80
- walk(child.children, depth + 1, networkRequestTime);
81
- }
82
- }, '');
83
- }
84
-
85
- walk(tree, 0);
86
- }
87
-
88
- /**
89
- * Get stats about the longest initiator chain (as determined by time duration)
90
- * @param {LH.Artifacts.CriticalRequestNode} tree
91
- * @return {{duration: number, length: number, transferSize: number}}
92
- */
93
- static _getLongestChain(tree) {
94
- const longest = {
95
- duration: 0,
96
- length: 0,
97
- transferSize: 0,
98
- };
99
- CriticalRequestChains._traverse(tree, opts => {
100
- const duration = opts.chainDuration;
101
- if (duration > longest.duration) {
102
- longest.duration = duration;
103
- longest.transferSize = opts.chainTransferSize;
104
- longest.length = opts.depth;
105
- }
106
- });
107
- // Always return the longest chain + 1 because the depth is zero indexed.
108
- longest.length++;
109
- return longest;
110
- }
111
-
112
- /**
113
- * @param {LH.Artifacts.CriticalRequestNode} tree
114
- * @return {LH.Audit.Details.SimpleCriticalRequestNode}
115
- */
116
- static flattenRequests(tree) {
117
- /** @type {LH.Audit.Details.SimpleCriticalRequestNode} */
118
- const flattendChains = {};
119
- /** @type {Map<string, LH.Audit.Details.SimpleCriticalRequestNode[string]>} */
120
- const chainMap = new Map();
121
-
122
- /** @param {CrcNodeInfo} opts */
123
- function flatten(opts) {
124
- const request = opts.node.request;
125
- const simpleRequest = {
126
- url: request.url,
127
- startTime: request.networkRequestTime / 1000,
128
- endTime: request.networkEndTime / 1000,
129
- responseReceivedTime: request.responseHeadersEndTime / 1000,
130
- transferSize: request.transferSize,
131
- };
132
-
133
- let chain = chainMap.get(opts.id);
134
- if (chain) {
135
- chain.request = simpleRequest;
136
- } else {
137
- chain = {
138
- request: simpleRequest,
139
- };
140
- flattendChains[opts.id] = chain;
141
- }
142
-
143
- if (opts.node.children) {
144
- for (const chainId of Object.keys(opts.node.children)) {
145
- // Note: cast should be Partial<>, but filled in when child node is traversed.
146
- const childChain = /** @type {LH.Audit.Details.SimpleCriticalRequestNode[string]} */ ({
147
- request: {},
148
- });
149
- chainMap.set(chainId, childChain);
150
- if (!chain.children) {
151
- chain.children = {};
152
- }
153
- chain.children[chainId] = childChain;
154
- }
155
- }
156
- chainMap.set(opts.id, chain);
157
- }
158
-
159
- CriticalRequestChains._traverse(tree, flatten);
160
-
161
- return flattendChains;
162
- }
163
-
164
- /**
165
- * Audits the page to give a score for First Meaningful Paint.
166
- * @param {LH.Artifacts} artifacts The artifacts from the gather phase.
167
- * @param {LH.Audit.Context} context
168
- * @return {Promise<LH.Audit.Product>}
169
- */
170
- static async audit(artifacts, context) {
171
- const settings = context.settings;
172
- const trace = artifacts.Trace;
173
- const devtoolsLog = artifacts.DevtoolsLog;
174
- const {URL, SourceMaps} = artifacts;
175
- const chains =
176
- await ComputedChains.request({settings, devtoolsLog, trace, URL, SourceMaps}, context);
177
- let chainCount = 0;
178
- /**
179
- * @param {LH.Audit.Details.SimpleCriticalRequestNode} node
180
- * @param {number} depth
181
- */
182
- function walk(node, depth) {
183
- const childIds = Object.keys(node);
184
-
185
- childIds.forEach(id => {
186
- const child = node[id];
187
- if (child.children) {
188
- walk(child.children, depth + 1);
189
- } else {
190
- // if the node doesn't have a children field, then it is a leaf, so +1
191
- chainCount++;
192
- }
193
- }, '');
194
- }
195
- // Convert
196
- const flattenedChains = CriticalRequestChains.flattenRequests(chains);
197
-
198
- // Account for initial navigation
199
- const initialNavKey = Object.keys(flattenedChains)[0];
200
- const initialNavChildren = initialNavKey && flattenedChains[initialNavKey].children;
201
- if (initialNavChildren && Object.keys(initialNavChildren).length > 0) {
202
- walk(initialNavChildren, 0);
203
- }
204
-
205
- const longestChain = CriticalRequestChains._getLongestChain(chains);
206
-
207
- return {
208
- score: Number(chainCount === 0),
209
- notApplicable: chainCount === 0,
210
- displayValue: chainCount ? str_(UIStrings.displayValue, {itemCount: chainCount}) : '',
211
- details: {
212
- type: 'criticalrequestchain',
213
- chains: flattenedChains,
214
- longestChain,
215
- },
216
- };
217
- }
218
- }
219
-
220
- export default CriticalRequestChains;
221
- export {UIStrings};
@@ -1,32 +0,0 @@
1
- export default DOMSize;
2
- declare class DOMSize extends Audit {
3
- /**
4
- * @return {LH.Audit.ScoreOptions}
5
- */
6
- static get defaultOptions(): LH.Audit.ScoreOptions;
7
- /**
8
- * @param {LH.Artifacts} artifacts
9
- * @param {LH.Audit.Context} context
10
- * @return {Promise<number|undefined>}
11
- */
12
- static computeTbtImpact(artifacts: LH.Artifacts, context: LH.Audit.Context): Promise<number | undefined>;
13
- /**
14
- * @param {LH.Artifacts} artifacts
15
- * @param {LH.Audit.Context} context
16
- * @return {Promise<LH.Audit.Product>}
17
- */
18
- static audit(artifacts: LH.Artifacts, context: LH.Audit.Context): Promise<LH.Audit.Product>;
19
- }
20
- export namespace UIStrings {
21
- let title: string;
22
- let failureTitle: string;
23
- let description: string;
24
- let columnStatistic: string;
25
- let columnValue: string;
26
- let displayValue: string;
27
- let statisticDOMElements: string;
28
- let statisticDOMDepth: string;
29
- let statisticDOMWidth: string;
30
- }
31
- import { Audit } from '../audit.js';
32
- //# sourceMappingURL=dom-size.d.ts.map