lighthouse 11.3.0-dev.20231205 → 11.3.0-dev.20231207
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/core/audits/bf-cache.d.ts +1 -0
- package/core/audits/bf-cache.js +11 -1
- package/core/audits/byte-efficiency/byte-efficiency-audit.d.ts +0 -24
- package/core/audits/byte-efficiency/byte-efficiency-audit.js +0 -102
- package/core/audits/byte-efficiency/duplicated-javascript.d.ts +0 -6
- package/core/audits/byte-efficiency/duplicated-javascript.js +9 -38
- package/core/audits/byte-efficiency/legacy-javascript.d.ts +0 -13
- package/core/audits/byte-efficiency/legacy-javascript.js +2 -36
- package/core/audits/byte-efficiency/unminified-css.js +2 -2
- package/core/audits/byte-efficiency/unminified-javascript.js +2 -3
- package/core/audits/byte-efficiency/unused-javascript.js +10 -11
- package/core/audits/resource-summary.d.ts +11 -0
- package/core/audits/resource-summary.js +86 -0
- package/core/computed/unused-css.js +2 -2
- package/core/config/default-config.js +2 -0
- package/core/config/filters.js +1 -0
- package/core/gather/base-artifacts.js +2 -1
- package/core/lib/i18n/i18n.d.ts +2 -2
- package/core/lib/i18n/i18n.js +2 -2
- package/core/lib/network-request.js +4 -1
- package/core/lib/script-helpers.d.ts +34 -5
- package/core/lib/script-helpers.js +136 -0
- package/dist/report/bundle.esm.js +24 -9
- package/dist/report/flow.js +25 -10
- package/dist/report/standalone.js +25 -10
- package/package.json +1 -1
- package/report/assets/styles.css +20 -5
- package/report/assets/templates.html +1 -1
- package/report/clients/standalone.js +1 -0
- package/report/renderer/components.js +2 -2
- package/report/renderer/report-renderer.js +4 -0
- package/report/types/report-renderer.d.ts +2 -0
- package/shared/localization/locales/en-US.json +3 -0
- package/shared/localization/locales/en-XL.json +3 -0
- package/tsconfig.json +1 -0
- package/types/artifacts.d.ts +2 -0
|
@@ -614,7 +614,10 @@ class NetworkRequest {
|
|
|
614
614
|
* @return {boolean}
|
|
615
615
|
*/
|
|
616
616
|
static isContentEncoded(record) {
|
|
617
|
-
|
|
617
|
+
// FYI: older devtools logs (like our test fixtures) seems to be lower case, while modern logs
|
|
618
|
+
// are Cased-Like-This.
|
|
619
|
+
const pattern = /^content-encoding$/i;
|
|
620
|
+
return record.responseHeaders.some(item => item.name.match(pattern));
|
|
618
621
|
}
|
|
619
622
|
|
|
620
623
|
/**
|
|
@@ -4,14 +4,43 @@
|
|
|
4
4
|
* @return {LH.Artifacts.NetworkRequest|undefined}
|
|
5
5
|
*/
|
|
6
6
|
export function getRequestForScript(networkRecords: LH.Artifacts.NetworkRequest[], script: LH.Artifacts.Script): LH.Artifacts.NetworkRequest | undefined;
|
|
7
|
-
/**
|
|
8
|
-
* @license
|
|
9
|
-
* Copyright 2022 Google LLC
|
|
10
|
-
* SPDX-License-Identifier: Apache-2.0
|
|
11
|
-
*/
|
|
12
7
|
/**
|
|
13
8
|
* @param {LH.Artifacts.Script} script
|
|
14
9
|
* @return {boolean}
|
|
15
10
|
*/
|
|
16
11
|
export function isInline(script: LH.Artifacts.Script): boolean;
|
|
12
|
+
/**
|
|
13
|
+
* Estimates the number of bytes the content of this network record would have consumed on the network based on the
|
|
14
|
+
* uncompressed size (totalBytes). Uses the actual transfer size from the network record if applicable,
|
|
15
|
+
* minus the size of the response headers.
|
|
16
|
+
*
|
|
17
|
+
* This differs from `estimateTransferSize` only in that is subtracts the response headers from the estimate.
|
|
18
|
+
*
|
|
19
|
+
* @param {LH.Artifacts.NetworkRequest|undefined} networkRecord
|
|
20
|
+
* @param {number} totalBytes Uncompressed size of the resource
|
|
21
|
+
* @param {LH.Crdp.Network.ResourceType=} resourceType
|
|
22
|
+
* @return {number}
|
|
23
|
+
*/
|
|
24
|
+
export function estimateCompressedContentSize(networkRecord: LH.Artifacts.NetworkRequest | undefined, totalBytes: number, resourceType?: LH.Crdp.Network.ResourceType | undefined): number;
|
|
25
|
+
/**
|
|
26
|
+
* Estimates the number of bytes this network record would have consumed on the network based on the
|
|
27
|
+
* uncompressed size (totalBytes). Uses the actual transfer size from the network record if applicable.
|
|
28
|
+
*
|
|
29
|
+
* @param {LH.Artifacts.NetworkRequest|undefined} networkRecord
|
|
30
|
+
* @param {number} totalBytes Uncompressed size of the resource
|
|
31
|
+
* @param {LH.Crdp.Network.ResourceType=} resourceType
|
|
32
|
+
* @return {number}
|
|
33
|
+
*/
|
|
34
|
+
export function estimateTransferSize(networkRecord: LH.Artifacts.NetworkRequest | undefined, totalBytes: number, resourceType?: LH.Crdp.Network.ResourceType | undefined): number;
|
|
35
|
+
/**
|
|
36
|
+
* Utility function to estimate the ratio of the compression on the resource.
|
|
37
|
+
* This excludes the size of the response headers.
|
|
38
|
+
* Also caches the calculation.
|
|
39
|
+
* @param {Map<string, number>} compressionRatioByUrl
|
|
40
|
+
* @param {string} url
|
|
41
|
+
* @param {LH.Artifacts} artifacts
|
|
42
|
+
* @param {Array<LH.Artifacts.NetworkRequest>} networkRecords
|
|
43
|
+
*/
|
|
44
|
+
export function estimateCompressionRatioForContent(compressionRatioByUrl: Map<string, number>, url: string, artifacts: LH.Artifacts, networkRecords: Array<LH.Artifacts.NetworkRequest>): number;
|
|
45
|
+
import { NetworkRequest } from './network-request.js';
|
|
17
46
|
//# sourceMappingURL=script-helpers.d.ts.map
|
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
+
import {NetworkRequest} from './network-request.js';
|
|
8
|
+
|
|
7
9
|
/**
|
|
8
10
|
* @param {LH.Artifacts.Script} script
|
|
9
11
|
* @return {boolean}
|
|
@@ -25,7 +27,141 @@ function getRequestForScript(networkRecords, script) {
|
|
|
25
27
|
return networkRequest;
|
|
26
28
|
}
|
|
27
29
|
|
|
30
|
+
/**
|
|
31
|
+
* Estimates the number of bytes this network record would have consumed on the network based on the
|
|
32
|
+
* uncompressed size (totalBytes). Uses the actual transfer size from the network record if applicable.
|
|
33
|
+
*
|
|
34
|
+
* @param {LH.Artifacts.NetworkRequest|undefined} networkRecord
|
|
35
|
+
* @param {number} totalBytes Uncompressed size of the resource
|
|
36
|
+
* @param {LH.Crdp.Network.ResourceType=} resourceType
|
|
37
|
+
* @return {number}
|
|
38
|
+
*/
|
|
39
|
+
function estimateTransferSize(networkRecord, totalBytes, resourceType) {
|
|
40
|
+
if (!networkRecord) {
|
|
41
|
+
// We don't know how many bytes this asset used on the network, but we can guess it was
|
|
42
|
+
// roughly the size of the content gzipped.
|
|
43
|
+
// See https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/optimize-encoding-and-transfer for specific CSS/Script examples
|
|
44
|
+
// See https://discuss.httparchive.org/t/file-size-and-compression-savings/145 for fallback multipliers
|
|
45
|
+
switch (resourceType) {
|
|
46
|
+
case 'Stylesheet':
|
|
47
|
+
// Stylesheets tend to compress extremely well.
|
|
48
|
+
return Math.round(totalBytes * 0.2);
|
|
49
|
+
case 'Script':
|
|
50
|
+
case 'Document':
|
|
51
|
+
// Scripts and HTML compress fairly well too.
|
|
52
|
+
return Math.round(totalBytes * 0.33);
|
|
53
|
+
default:
|
|
54
|
+
// Otherwise we'll just fallback to the average savings in HTTPArchive
|
|
55
|
+
return Math.round(totalBytes * 0.5);
|
|
56
|
+
}
|
|
57
|
+
} else if (networkRecord.resourceType === resourceType) {
|
|
58
|
+
// This was a regular standalone asset, just use the transfer size.
|
|
59
|
+
return networkRecord.transferSize || 0;
|
|
60
|
+
} else {
|
|
61
|
+
// This was an asset that was inlined in a different resource type (e.g. HTML document).
|
|
62
|
+
// Use the compression ratio of the resource to estimate the total transferred bytes.
|
|
63
|
+
const transferSize = networkRecord.transferSize || 0;
|
|
64
|
+
const resourceSize = networkRecord.resourceSize || 0;
|
|
65
|
+
// Get the compression ratio, if it's an invalid number, assume no compression.
|
|
66
|
+
const compressionRatio = Number.isFinite(resourceSize) && resourceSize > 0 ?
|
|
67
|
+
(transferSize / resourceSize) : 1;
|
|
68
|
+
return Math.round(totalBytes * compressionRatio);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Estimates the number of bytes the content of this network record would have consumed on the network based on the
|
|
74
|
+
* uncompressed size (totalBytes). Uses the actual transfer size from the network record if applicable,
|
|
75
|
+
* minus the size of the response headers.
|
|
76
|
+
*
|
|
77
|
+
* This differs from `estimateTransferSize` only in that is subtracts the response headers from the estimate.
|
|
78
|
+
*
|
|
79
|
+
* @param {LH.Artifacts.NetworkRequest|undefined} networkRecord
|
|
80
|
+
* @param {number} totalBytes Uncompressed size of the resource
|
|
81
|
+
* @param {LH.Crdp.Network.ResourceType=} resourceType
|
|
82
|
+
* @return {number}
|
|
83
|
+
*/
|
|
84
|
+
function estimateCompressedContentSize(networkRecord, totalBytes, resourceType) {
|
|
85
|
+
if (!networkRecord) {
|
|
86
|
+
// We don't know how many bytes this asset used on the network, but we can guess it was
|
|
87
|
+
// roughly the size of the content gzipped.
|
|
88
|
+
// See https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/optimize-encoding-and-transfer for specific CSS/Script examples
|
|
89
|
+
// See https://discuss.httparchive.org/t/file-size-and-compression-savings/145 for fallback multipliers
|
|
90
|
+
switch (resourceType) {
|
|
91
|
+
case 'Stylesheet':
|
|
92
|
+
// Stylesheets tend to compress extremely well.
|
|
93
|
+
return Math.round(totalBytes * 0.2);
|
|
94
|
+
case 'Script':
|
|
95
|
+
case 'Document':
|
|
96
|
+
// Scripts and HTML compress fairly well too.
|
|
97
|
+
return Math.round(totalBytes * 0.33);
|
|
98
|
+
default:
|
|
99
|
+
// Otherwise we'll just fallback to the average savings in HTTPArchive
|
|
100
|
+
return Math.round(totalBytes * 0.5);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Get the size of the response body on the network.
|
|
105
|
+
let contentTransferSize = networkRecord.transferSize || 0;
|
|
106
|
+
if (!NetworkRequest.isContentEncoded(networkRecord)) {
|
|
107
|
+
// This is not encoded, so we can use resourceSize directly.
|
|
108
|
+
// This would be equivalent to transfer size minus headers transfer size, but transfer size
|
|
109
|
+
// may also include bytes for SSL connection etc.
|
|
110
|
+
contentTransferSize = networkRecord.resourceSize;
|
|
111
|
+
} else if (networkRecord.responseHeadersTransferSize) {
|
|
112
|
+
// Subtract the size of the encoded headers.
|
|
113
|
+
contentTransferSize =
|
|
114
|
+
Math.max(0, contentTransferSize - networkRecord.responseHeadersTransferSize);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
if (networkRecord.resourceType === resourceType) {
|
|
118
|
+
// This was a regular standalone asset, just use the transfer size.
|
|
119
|
+
return contentTransferSize;
|
|
120
|
+
} else {
|
|
121
|
+
// This was an asset that was inlined in a different resource type (e.g. HTML document).
|
|
122
|
+
// Use the compression ratio of the resource to estimate the total transferred bytes.
|
|
123
|
+
const resourceSize = networkRecord.resourceSize || 0;
|
|
124
|
+
// Get the compression ratio, if it's an invalid number, assume no compression.
|
|
125
|
+
const compressionRatio = Number.isFinite(resourceSize) && resourceSize > 0 ?
|
|
126
|
+
(contentTransferSize / resourceSize) : 1;
|
|
127
|
+
return Math.round(totalBytes * compressionRatio);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Utility function to estimate the ratio of the compression on the resource.
|
|
133
|
+
* This excludes the size of the response headers.
|
|
134
|
+
* Also caches the calculation.
|
|
135
|
+
* @param {Map<string, number>} compressionRatioByUrl
|
|
136
|
+
* @param {string} url
|
|
137
|
+
* @param {LH.Artifacts} artifacts
|
|
138
|
+
* @param {Array<LH.Artifacts.NetworkRequest>} networkRecords
|
|
139
|
+
*/
|
|
140
|
+
function estimateCompressionRatioForContent(compressionRatioByUrl, url,
|
|
141
|
+
artifacts, networkRecords) {
|
|
142
|
+
let compressionRatio = compressionRatioByUrl.get(url);
|
|
143
|
+
if (compressionRatio !== undefined) return compressionRatio;
|
|
144
|
+
|
|
145
|
+
const script = artifacts.Scripts.find(script => script.url === url);
|
|
146
|
+
|
|
147
|
+
if (!script) {
|
|
148
|
+
// Can't find content, so just use 1.
|
|
149
|
+
compressionRatio = 1;
|
|
150
|
+
} else {
|
|
151
|
+
const networkRecord = getRequestForScript(networkRecords, script);
|
|
152
|
+
const contentLength = networkRecord?.resourceSize || script.length || 0;
|
|
153
|
+
const compressedSize = estimateCompressedContentSize(networkRecord, contentLength, 'Script');
|
|
154
|
+
compressionRatio = compressedSize / contentLength;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
compressionRatioByUrl.set(url, compressionRatio);
|
|
158
|
+
return compressionRatio;
|
|
159
|
+
}
|
|
160
|
+
|
|
28
161
|
export {
|
|
29
162
|
getRequestForScript,
|
|
30
163
|
isInline,
|
|
164
|
+
estimateCompressedContentSize,
|
|
165
|
+
estimateTransferSize,
|
|
166
|
+
estimateCompressionRatioForContent,
|
|
31
167
|
};
|