lighthouse 12.5.1 → 12.6.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/cli/run.js +1 -1
- package/cli/test/smokehouse/config/exclusions.js +2 -0
- package/cli/test/smokehouse/lib/concurrent-mapper.d.ts +3 -3
- package/core/audits/audit.d.ts +1 -1
- package/core/audits/audit.js +3 -2
- package/core/audits/bootup-time.d.ts +1 -1
- package/core/audits/bootup-time.js +3 -3
- package/core/audits/byte-efficiency/byte-efficiency-audit.js +1 -1
- package/core/audits/byte-efficiency/duplicated-javascript.js +1 -1
- package/core/audits/byte-efficiency/efficient-animated-content.js +1 -1
- package/core/audits/byte-efficiency/legacy-javascript.js +2 -3
- package/core/audits/byte-efficiency/modern-image-formats.js +1 -1
- package/core/audits/byte-efficiency/offscreen-images.js +4 -4
- package/core/audits/byte-efficiency/render-blocking-resources.js +4 -4
- package/core/audits/byte-efficiency/total-byte-weight.d.ts +1 -1
- package/core/audits/byte-efficiency/total-byte-weight.js +2 -2
- package/core/audits/byte-efficiency/unminified-css.js +1 -1
- package/core/audits/byte-efficiency/unminified-javascript.js +1 -1
- package/core/audits/byte-efficiency/unused-css-rules.js +2 -2
- package/core/audits/byte-efficiency/unused-javascript.js +1 -1
- package/core/audits/byte-efficiency/uses-long-cache-ttl.d.ts +1 -1
- package/core/audits/byte-efficiency/uses-long-cache-ttl.js +2 -2
- package/core/audits/byte-efficiency/uses-optimized-images.js +2 -2
- package/core/audits/byte-efficiency/uses-responsive-images.d.ts +1 -1
- package/core/audits/byte-efficiency/uses-responsive-images.js +1 -1
- package/core/audits/byte-efficiency/uses-text-compression.js +1 -1
- package/core/audits/clickjacking-mitigation.js +2 -2
- package/core/audits/critical-request-chains.js +3 -3
- package/core/audits/csp-xss.js +2 -2
- package/core/audits/diagnostics.js +3 -3
- package/core/audits/dobetterweb/charset.js +2 -2
- package/core/audits/dobetterweb/doctype.js +2 -2
- package/core/audits/dobetterweb/dom-size.d.ts +1 -1
- package/core/audits/dobetterweb/dom-size.js +3 -3
- package/core/audits/dobetterweb/uses-http2.js +2 -2
- package/core/audits/final-screenshot.js +2 -2
- package/core/audits/font-display.js +2 -2
- package/core/audits/has-hsts.js +2 -2
- package/core/audits/image-size-responsive.d.ts +3 -2
- package/core/audits/image-size-responsive.js +30 -4
- package/core/audits/insights/{use-cache-insight.d.ts → cache-insight.d.ts} +3 -3
- package/core/audits/insights/{use-cache-insight.js → cache-insight.js} +15 -13
- package/core/audits/insights/cls-culprits-insight.js +3 -3
- package/core/audits/insights/document-latency-insight.js +1 -1
- package/core/audits/insights/dom-size-insight.js +1 -1
- package/core/audits/insights/duplicated-javascript-insight.d.ts +13 -0
- package/core/audits/insights/duplicated-javascript-insight.js +36 -9
- package/core/audits/insights/font-display-insight.js +1 -1
- package/core/audits/insights/forced-reflow-insight.js +1 -1
- package/core/audits/insights/image-delivery-insight.js +1 -1
- package/core/audits/insights/insight-audit.d.ts +11 -9
- package/core/audits/insights/insight-audit.js +37 -35
- package/core/audits/insights/interaction-to-next-paint-insight.js +3 -6
- package/core/audits/insights/lcp-discovery-insight.js +6 -3
- package/core/audits/insights/lcp-phases-insight.js +3 -6
- package/core/audits/insights/legacy-javascript-insight.d.ts +23 -0
- package/core/audits/insights/legacy-javascript-insight.js +101 -0
- package/core/audits/insights/modern-http-insight.d.ts +11 -0
- package/core/audits/insights/modern-http-insight.js +53 -0
- package/core/audits/insights/network-dependency-tree-insight.d.ts +5 -0
- package/core/audits/insights/network-dependency-tree-insight.js +35 -13
- package/core/audits/insights/render-blocking-insight.js +1 -1
- package/core/audits/insights/slow-css-selector-insight.js +3 -1
- package/core/audits/insights/third-parties-insight.d.ts +3 -3
- package/core/audits/insights/third-parties-insight.js +28 -23
- package/core/audits/insights/viewport-insight.js +1 -1
- package/core/audits/is-on-https.js +2 -2
- package/core/audits/largest-contentful-paint-element.js +3 -3
- package/core/audits/layout-shifts.js +4 -4
- package/core/audits/lcp-lazy-loaded.js +1 -1
- package/core/audits/long-tasks.d.ts +1 -1
- package/core/audits/long-tasks.js +3 -3
- package/core/audits/main-thread-tasks.js +2 -2
- package/core/audits/mainthread-work-breakdown.d.ts +1 -1
- package/core/audits/mainthread-work-breakdown.js +2 -2
- package/core/audits/manual/manual-audit.d.ts +1 -1
- package/core/audits/metrics/cumulative-layout-shift.d.ts +1 -1
- package/core/audits/metrics/cumulative-layout-shift.js +2 -2
- package/core/audits/metrics/first-contentful-paint.js +3 -3
- package/core/audits/metrics/first-meaningful-paint.js +1 -1
- package/core/audits/metrics/interaction-to-next-paint.d.ts +1 -1
- package/core/audits/metrics/interaction-to-next-paint.js +2 -2
- package/core/audits/metrics/interactive.js +3 -3
- package/core/audits/metrics/largest-contentful-paint.js +3 -3
- package/core/audits/metrics/max-potential-fid.d.ts +1 -1
- package/core/audits/metrics/max-potential-fid.js +3 -3
- package/core/audits/metrics/speed-index.js +3 -3
- package/core/audits/metrics/total-blocking-time.js +3 -3
- package/core/audits/metrics.js +3 -3
- package/core/audits/network-requests.js +2 -2
- package/core/audits/network-rtt.js +2 -2
- package/core/audits/network-server-latency.js +2 -2
- package/core/audits/origin-isolation.js +2 -2
- package/core/audits/predictive-perf.js +3 -3
- package/core/audits/preload-fonts.js +2 -2
- package/core/audits/prioritize-lcp-image.js +3 -3
- package/core/audits/redirects.js +3 -3
- package/core/audits/resource-summary.js +2 -2
- package/core/audits/screenshot-thumbnails.js +2 -2
- package/core/audits/script-treemap-data.js +32 -2
- package/core/audits/seo/canonical.js +2 -2
- package/core/audits/seo/http-status-code.js +2 -2
- package/core/audits/seo/is-crawlable.js +2 -2
- package/core/audits/server-response-time.js +2 -2
- package/core/audits/third-party-cookies.js +1 -1
- package/core/audits/third-party-facades.js +2 -2
- package/core/audits/third-party-summary.js +2 -2
- package/core/audits/user-timings.d.ts +1 -1
- package/core/audits/user-timings.js +2 -2
- package/core/audits/uses-rel-preconnect.js +3 -3
- package/core/audits/uses-rel-preload.js +3 -3
- package/core/audits/valid-source-maps.js +2 -2
- package/core/audits/work-during-interaction.js +3 -3
- package/core/computed/critical-request-chains.d.ts +1 -1
- package/core/computed/document-urls.d.ts +4 -1
- package/core/computed/entity-classification.d.ts +1 -1
- package/core/computed/image-records.d.ts +1 -1
- package/core/computed/js-bundles.d.ts +1 -1
- package/core/computed/lcp-image-record.d.ts +1 -1
- package/core/computed/load-simulator.d.ts +1 -1
- package/core/computed/main-resource.d.ts +1 -1
- package/core/computed/main-thread-tasks.d.ts +1 -1
- package/core/computed/metrics/cumulative-layout-shift.d.ts +10 -1
- package/core/computed/metrics/first-contentful-paint-all-frames.d.ts +1 -1
- package/core/computed/metrics/first-contentful-paint.d.ts +1 -1
- package/core/computed/metrics/interactive.d.ts +1 -1
- package/core/computed/metrics/lantern-first-contentful-paint.d.ts +1 -1
- package/core/computed/metrics/lantern-interactive.d.ts +1 -1
- package/core/computed/metrics/lantern-largest-contentful-paint.d.ts +1 -1
- package/core/computed/metrics/lantern-max-potential-fid.d.ts +1 -1
- package/core/computed/metrics/lantern-speed-index.d.ts +1 -1
- package/core/computed/metrics/lantern-total-blocking-time.d.ts +1 -1
- package/core/computed/metrics/largest-contentful-paint-all-frames.d.ts +1 -1
- package/core/computed/metrics/largest-contentful-paint.d.ts +1 -1
- package/core/computed/metrics/lcp-breakdown.d.ts +5 -1
- package/core/computed/metrics/max-potential-fid.d.ts +1 -1
- package/core/computed/metrics/responsiveness.d.ts +1 -1
- package/core/computed/metrics/speed-index.d.ts +1 -1
- package/core/computed/metrics/time-to-first-byte.d.ts +1 -1
- package/core/computed/metrics/timing-summary.d.ts +4 -1
- package/core/computed/metrics/total-blocking-time.d.ts +1 -1
- package/core/computed/module-duplication.d.ts +5 -1
- package/core/computed/navigation-insights.d.ts +1 -1
- package/core/computed/network-analysis.d.ts +1 -1
- package/core/computed/network-records.d.ts +1 -1
- package/core/computed/page-dependency-graph.d.ts +1 -1
- package/core/computed/processed-navigation.d.ts +1 -1
- package/core/computed/processed-trace.d.ts +1 -1
- package/core/computed/resource-summary.d.ts +1 -1
- package/core/computed/screenshots.d.ts +4 -1
- package/core/computed/speedline.d.ts +1 -1
- package/core/computed/tbt-impact-tasks.d.ts +1 -1
- package/core/computed/trace-engine-result.d.ts +1 -1
- package/core/computed/unused-css.d.ts +1 -1
- package/core/computed/unused-javascript-summary.d.ts +1 -1
- package/core/computed/user-timings.d.ts +1 -1
- package/core/computed/viewport-meta.d.ts +1 -1
- package/core/config/default-config.js +11 -6
- package/core/config/experimental-config.js +3 -2
- package/core/gather/driver/network-monitor.d.ts +1 -1
- package/core/gather/driver/network.d.ts +1 -1
- package/core/gather/driver.d.ts +1 -1
- package/core/gather/gatherers/devtools-log.d.ts +1 -1
- package/core/gather/gatherers/dobetterweb/optimized-images.js +3 -10
- package/core/gather/gatherers/trace-elements.d.ts +3 -4
- package/core/gather/gatherers/trace-elements.js +6 -8
- package/core/gather/gatherers/trace.js +0 -3
- package/core/gather/navigation-runner.d.ts +1 -1
- package/core/gather/snapshot-runner.d.ts +1 -1
- package/core/gather/timespan-runner.d.ts +1 -1
- package/core/index.d.ts +6 -6
- package/core/lib/asset-saver.d.ts +1 -1
- package/core/lib/asset-saver.js +1 -1
- package/core/lib/bf-cache-strings.js +2 -0
- package/core/lib/deprecations-strings.d.ts +71 -76
- package/core/lib/deprecations-strings.js +22 -25
- package/core/lib/i18n/README.md +1 -1
- package/core/lib/i18n/i18n.d.ts +1 -1
- package/core/lib/i18n/i18n.js +4 -4
- package/core/lib/legacy-javascript/legacy-javascript.js +4 -11
- package/core/lib/legacy-javascript/package.json +14 -0
- package/core/lib/page-functions.d.ts +1 -1
- package/core/lib/stack-packs.js +1 -1
- package/core/lib/tracehouse/cpu-profile-model.d.ts +1 -1
- package/core/lib/tracehouse/main-thread-tasks.d.ts +3 -3
- package/core/lib/tracehouse/main-thread-tasks.js +8 -0
- package/core/lib/tracehouse/trace-processor.d.ts +1 -1
- package/core/lib/traces/metric-trace-events.d.ts +2 -2
- package/core/runner.js +2 -1
- package/core/scoring.d.ts +539 -3
- package/core/user-flow.d.ts +6 -6
- package/dist/report/bundle.esm.js +89 -19
- package/dist/report/flow.js +92 -22
- package/dist/report/standalone.js +89 -19
- package/flow-report/src/i18n/i18n.d.ts +6 -2
- package/package.json +17 -16
- package/readme.md +1 -1
- package/report/README.md +1 -1
- package/report/assets/styles.css +76 -9
- package/report/assets/templates.html +3 -1
- package/report/clients/standalone.js +6 -4
- package/report/renderer/category-renderer.d.ts +2 -2
- package/report/renderer/components.js +3 -9
- package/report/renderer/crc-details-renderer.d.ts +13 -31
- package/report/renderer/crc-details-renderer.js +49 -47
- package/report/renderer/details-renderer.d.ts +1 -1
- package/report/renderer/details-renderer.js +6 -0
- package/report/renderer/dom.js +7 -0
- package/report/renderer/features-util.d.ts +1 -1
- package/report/renderer/performance-category-renderer.d.ts +28 -2
- package/report/renderer/performance-category-renderer.js +121 -3
- package/report/renderer/report-utils.d.ts +3 -1
- package/report/renderer/report-utils.js +11 -4
- package/report/renderer/topbar-features.js +1 -9
- package/shared/localization/format.d.ts +1 -1
- package/shared/localization/locales/ar-XB.json +66 -6
- package/shared/localization/locales/ar.json +66 -6
- package/shared/localization/locales/bg.json +66 -6
- package/shared/localization/locales/ca.json +66 -6
- package/shared/localization/locales/cs.json +66 -6
- package/shared/localization/locales/da.json +66 -6
- package/shared/localization/locales/de.json +66 -6
- package/shared/localization/locales/el.json +66 -6
- package/shared/localization/locales/en-GB.json +66 -6
- package/shared/localization/locales/en-US.json +87 -36
- package/shared/localization/locales/en-XA.json +0 -6
- package/shared/localization/locales/en-XL.json +87 -36
- package/shared/localization/locales/es-419.json +66 -6
- package/shared/localization/locales/es.json +67 -7
- package/shared/localization/locales/fi.json +66 -6
- package/shared/localization/locales/fil.json +66 -6
- package/shared/localization/locales/fr.json +66 -6
- package/shared/localization/locales/he.json +66 -6
- package/shared/localization/locales/hi.json +66 -6
- package/shared/localization/locales/hr.json +66 -6
- package/shared/localization/locales/hu.json +66 -6
- package/shared/localization/locales/id.json +66 -6
- package/shared/localization/locales/it.json +67 -7
- package/shared/localization/locales/ja.json +66 -6
- package/shared/localization/locales/ko.json +66 -6
- package/shared/localization/locales/lt.json +66 -6
- package/shared/localization/locales/lv.json +66 -6
- package/shared/localization/locales/nl.json +66 -6
- package/shared/localization/locales/no.json +66 -6
- package/shared/localization/locales/pl.json +66 -6
- package/shared/localization/locales/pt-PT.json +66 -6
- package/shared/localization/locales/pt.json +67 -7
- package/shared/localization/locales/ro.json +66 -6
- package/shared/localization/locales/ru.json +66 -6
- package/shared/localization/locales/sk.json +66 -6
- package/shared/localization/locales/sl.json +66 -6
- package/shared/localization/locales/sr-Latn.json +66 -6
- package/shared/localization/locales/sr.json +66 -6
- package/shared/localization/locales/sv.json +66 -6
- package/shared/localization/locales/ta.json +69 -9
- package/shared/localization/locales/te.json +66 -6
- package/shared/localization/locales/th.json +66 -6
- package/shared/localization/locales/tr.json +66 -6
- package/shared/localization/locales/uk.json +66 -6
- package/shared/localization/locales/vi.json +66 -6
- package/shared/localization/locales/zh-HK.json +67 -7
- package/shared/localization/locales/zh-TW.json +67 -7
- package/shared/localization/locales/zh.json +66 -6
- package/tsconfig-base.json +1 -1
- package/tsconfig.json +1 -0
- package/types/artifacts.d.ts +0 -2
- package/types/internal/node.d.ts +0 -16
- package/types/lhr/audit-details.d.ts +33 -1
- package/types/lhr/treemap.d.ts +5 -1
|
@@ -11,6 +11,8 @@
|
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
import {Audit} from './audit.js';
|
|
14
|
+
import {ImageRecords} from '../computed/image-records.js';
|
|
15
|
+
import {NetworkRecords} from '../computed/network-records.js';
|
|
14
16
|
import UrlUtils from '../lib/url-utils.js';
|
|
15
17
|
import * as i18n from '../lib/i18n/i18n.js';
|
|
16
18
|
|
|
@@ -77,9 +79,10 @@ function isSmallerThanViewport(imageRect, viewportDimensions) {
|
|
|
77
79
|
|
|
78
80
|
/**
|
|
79
81
|
* @param {LH.Artifacts.ImageElement} image
|
|
82
|
+
* @param {LH.Artifacts.ImageElementRecord | undefined} imageRecord
|
|
80
83
|
* @return {boolean}
|
|
81
84
|
*/
|
|
82
|
-
function isCandidate(image) {
|
|
85
|
+
function isCandidate(image, imageRecord) {
|
|
83
86
|
/** image-rendering solution for pixel art scaling.
|
|
84
87
|
* https://developer.mozilla.org/en-US/docs/Games/Techniques/Crisp_pixel_art_look
|
|
85
88
|
*/
|
|
@@ -96,6 +99,10 @@ function isCandidate(image) {
|
|
|
96
99
|
) {
|
|
97
100
|
return false;
|
|
98
101
|
}
|
|
102
|
+
// Check the actual mimeType before guessing, since file extension is not guaranteed
|
|
103
|
+
if (imageRecord?.mimeType === 'image/svg+xml') {
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
99
106
|
if (UrlUtils.guessMimeType(image.src) === 'image/svg+xml') {
|
|
100
107
|
return false;
|
|
101
108
|
}
|
|
@@ -243,19 +250,38 @@ class ImageSizeResponsive extends Audit {
|
|
|
243
250
|
failureTitle: str_(UIStrings.failureTitle),
|
|
244
251
|
description: str_(UIStrings.description),
|
|
245
252
|
requiredArtifacts: ['ImageElements', 'ViewportDimensions'],
|
|
253
|
+
__internalOptionalArtifacts: ['DevtoolsLog'],
|
|
246
254
|
};
|
|
247
255
|
}
|
|
248
256
|
|
|
249
257
|
/**
|
|
250
258
|
* @param {LH.Artifacts} artifacts
|
|
251
|
-
* @
|
|
259
|
+
* @param {LH.Audit.Context} context
|
|
260
|
+
* @return {Promise<LH.Audit.Product>}
|
|
252
261
|
*/
|
|
253
|
-
static audit(artifacts) {
|
|
262
|
+
static async audit(artifacts, context) {
|
|
254
263
|
const DPR = artifacts.ViewportDimensions.devicePixelRatio;
|
|
255
264
|
|
|
265
|
+
// Prepare ImageElementRecord map for retrieving the real mimeType
|
|
266
|
+
// Derived from ./is-on-https.js and ./byte-efficiency/uses-responsive-images.js
|
|
267
|
+
/** @type {Map<string, LH.Artifacts.ImageElementRecord>} */
|
|
268
|
+
const imageRecordsByURL = new Map();
|
|
269
|
+
|
|
270
|
+
if (artifacts.DevtoolsLog) {
|
|
271
|
+
// https://github.com/GoogleChrome/lighthouse/blob/main/docs/plugins.md#using-network-requests
|
|
272
|
+
// if DevtoolsLog is provided, use it to fetch image networkRecords
|
|
273
|
+
// else the empty imageRecordsByURL map will satisfy isCandidate with an undefined image and fallback to the original logic
|
|
274
|
+
const networkRecords = await NetworkRecords.request(artifacts.DevtoolsLog, context);
|
|
275
|
+
const images = await ImageRecords.request({
|
|
276
|
+
ImageElements: artifacts.ImageElements,
|
|
277
|
+
networkRecords,
|
|
278
|
+
}, context);
|
|
279
|
+
images.forEach(img => imageRecordsByURL.set(img.src, img));
|
|
280
|
+
}
|
|
281
|
+
|
|
256
282
|
const results = Array
|
|
257
283
|
.from(artifacts.ImageElements)
|
|
258
|
-
.filter(isCandidate)
|
|
284
|
+
.filter(image => isCandidate(image, imageRecordsByURL.get(image.src)))
|
|
259
285
|
.filter(imageHasNaturalDimensions)
|
|
260
286
|
.filter(image => !imageHasRightSize(image, DPR))
|
|
261
287
|
.filter(image => isVisible(image.clientRect, artifacts.ViewportDimensions))
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export default
|
|
2
|
-
declare class
|
|
1
|
+
export default CacheInsight;
|
|
2
|
+
declare class CacheInsight extends Audit {
|
|
3
3
|
/**
|
|
4
4
|
* @param {LH.Artifacts} artifacts
|
|
5
5
|
* @param {LH.Audit.Context} context
|
|
@@ -8,4 +8,4 @@ declare class UseCacheInsight extends Audit {
|
|
|
8
8
|
static audit(artifacts: LH.Artifacts, context: LH.Audit.Context): Promise<LH.Audit.Product>;
|
|
9
9
|
}
|
|
10
10
|
import { Audit } from '../audit.js';
|
|
11
|
-
//# sourceMappingURL=
|
|
11
|
+
//# sourceMappingURL=cache-insight.d.ts.map
|
|
@@ -4,27 +4,27 @@
|
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import {UIStrings} from '@paulirish/trace_engine/models/trace/insights/
|
|
7
|
+
import {UIStrings} from '@paulirish/trace_engine/models/trace/insights/Cache.js';
|
|
8
8
|
|
|
9
9
|
import {Audit} from '../audit.js';
|
|
10
10
|
import * as i18n from '../../lib/i18n/i18n.js';
|
|
11
11
|
import {adaptInsightToAuditProduct} from './insight-audit.js';
|
|
12
12
|
|
|
13
13
|
// eslint-disable-next-line max-len
|
|
14
|
-
const str_ = i18n.createIcuMessageFn('node_modules/@paulirish/trace_engine/models/trace/insights/
|
|
14
|
+
const str_ = i18n.createIcuMessageFn('node_modules/@paulirish/trace_engine/models/trace/insights/Cache.js', UIStrings);
|
|
15
15
|
|
|
16
|
-
class
|
|
16
|
+
class CacheInsight extends Audit {
|
|
17
17
|
/**
|
|
18
18
|
* @return {LH.Audit.Meta}
|
|
19
19
|
*/
|
|
20
20
|
static get meta() {
|
|
21
21
|
return {
|
|
22
|
-
id: '
|
|
22
|
+
id: 'cache-insight',
|
|
23
23
|
title: str_(UIStrings.title),
|
|
24
24
|
failureTitle: str_(UIStrings.title),
|
|
25
25
|
description: str_(UIStrings.description),
|
|
26
26
|
guidanceLevel: 3,
|
|
27
|
-
requiredArtifacts: ['
|
|
27
|
+
requiredArtifacts: ['Trace', 'SourceMaps'],
|
|
28
28
|
replacesAudits: ['uses-long-cache-ttl'],
|
|
29
29
|
};
|
|
30
30
|
}
|
|
@@ -35,27 +35,29 @@ class UseCacheInsight extends Audit {
|
|
|
35
35
|
* @return {Promise<LH.Audit.Product>}
|
|
36
36
|
*/
|
|
37
37
|
static async audit(artifacts, context) {
|
|
38
|
-
return adaptInsightToAuditProduct(artifacts, context, '
|
|
38
|
+
return adaptInsightToAuditProduct(artifacts, context, 'Cache', (insight) => {
|
|
39
39
|
/** @type {LH.Audit.Details.Table['headings']} */
|
|
40
40
|
const headings = [
|
|
41
41
|
/* eslint-disable max-len */
|
|
42
42
|
{key: 'url', valueType: 'url', label: str_(UIStrings.requestColumn)},
|
|
43
43
|
{key: 'cacheLifetimeMs', valueType: 'ms', label: str_(UIStrings.cacheTTL), displayUnit: 'duration'},
|
|
44
|
-
{key: '
|
|
44
|
+
{key: 'wastedBytes', valueType: 'bytes', label: str_(i18n.UIStrings.columnTransferSize), displayUnit: 'kb', granularity: 1},
|
|
45
45
|
/* eslint-enable max-len */
|
|
46
46
|
];
|
|
47
|
+
// TODO: this should be the sorting in the model (instead it sorts by transfer size...)
|
|
48
|
+
const values = insight.requests.sort((a, b) => b.wastedBytes - a.wastedBytes);
|
|
47
49
|
/** @type {LH.Audit.Details.Table['items']} */
|
|
48
|
-
const items =
|
|
49
|
-
url:
|
|
50
|
-
cacheLifetimeMs:
|
|
51
|
-
|
|
50
|
+
const items = values.map(value => ({
|
|
51
|
+
url: value.request.args.data.url,
|
|
52
|
+
cacheLifetimeMs: value.ttl * 1000,
|
|
53
|
+
wastedBytes: value.wastedBytes,
|
|
52
54
|
}));
|
|
53
55
|
return Audit.makeTableDetails(headings, items, {
|
|
54
|
-
sortedBy: ['
|
|
56
|
+
sortedBy: ['wastedBytes'],
|
|
55
57
|
skipSumming: ['cacheLifetimeMs'],
|
|
56
58
|
});
|
|
57
59
|
});
|
|
58
60
|
}
|
|
59
61
|
}
|
|
60
62
|
|
|
61
|
-
export default
|
|
63
|
+
export default CacheInsight;
|
|
@@ -39,7 +39,7 @@ class CLSCulpritsInsight extends Audit {
|
|
|
39
39
|
failureTitle: insightStr_(InsightUIStrings.title),
|
|
40
40
|
description: insightStr_(InsightUIStrings.description),
|
|
41
41
|
guidanceLevel: 3,
|
|
42
|
-
requiredArtifacts: ['
|
|
42
|
+
requiredArtifacts: ['Trace', 'TraceElements', 'SourceMaps'],
|
|
43
43
|
replacesAudits: ['layout-shifts', 'non-composited-animations', 'unsized-images'],
|
|
44
44
|
};
|
|
45
45
|
}
|
|
@@ -58,9 +58,9 @@ class CLSCulpritsInsight extends Audit {
|
|
|
58
58
|
|
|
59
59
|
/** @type {SubItem[]} */
|
|
60
60
|
const subItems = [];
|
|
61
|
-
for (const
|
|
61
|
+
for (const unsizedImage of culprits.unsizedImages) {
|
|
62
62
|
subItems.push({
|
|
63
|
-
extra: makeNodeItemForNodeId(TraceElements, backendNodeId),
|
|
63
|
+
extra: makeNodeItemForNodeId(TraceElements, unsizedImage.backendNodeId),
|
|
64
64
|
cause: insightStr_(InsightUIStrings.unsizedImages),
|
|
65
65
|
});
|
|
66
66
|
}
|
|
@@ -24,7 +24,7 @@ class DocumentLatencyInsight extends Audit {
|
|
|
24
24
|
failureTitle: str_(UIStrings.title),
|
|
25
25
|
description: str_(UIStrings.description),
|
|
26
26
|
guidanceLevel: 3,
|
|
27
|
-
requiredArtifacts: ['
|
|
27
|
+
requiredArtifacts: ['Trace', 'TraceElements', 'SourceMaps'],
|
|
28
28
|
replacesAudits: ['redirects', 'server-response-time', 'uses-text-compression'],
|
|
29
29
|
};
|
|
30
30
|
}
|
|
@@ -24,7 +24,7 @@ class DOMSizeInsight extends Audit {
|
|
|
24
24
|
failureTitle: str_(UIStrings.title),
|
|
25
25
|
description: str_(UIStrings.description),
|
|
26
26
|
guidanceLevel: 3,
|
|
27
|
-
requiredArtifacts: ['
|
|
27
|
+
requiredArtifacts: ['Trace', 'TraceElements', 'SourceMaps'],
|
|
28
28
|
replacesAudits: ['dom-size'],
|
|
29
29
|
};
|
|
30
30
|
}
|
|
@@ -1,4 +1,17 @@
|
|
|
1
1
|
export default DuplicatedJavaScriptInsight;
|
|
2
|
+
export type Item = LH.Audit.Details.TableItem & {
|
|
3
|
+
source: string;
|
|
4
|
+
subItems: {
|
|
5
|
+
type: "subitems";
|
|
6
|
+
items: SubItem[];
|
|
7
|
+
};
|
|
8
|
+
};
|
|
9
|
+
export type SubItem = {
|
|
10
|
+
url: string;
|
|
11
|
+
sourceTransferBytes: number | LH.Audit.Details.TextValue;
|
|
12
|
+
};
|
|
13
|
+
/** @typedef {LH.Audit.Details.TableItem & {source: string, subItems: {type: 'subitems', items: SubItem[]}}} Item */
|
|
14
|
+
/** @typedef {{url: string, sourceTransferBytes: number|LH.Audit.Details.TextValue}} SubItem */
|
|
2
15
|
declare class DuplicatedJavaScriptInsight extends Audit {
|
|
3
16
|
/**
|
|
4
17
|
* @param {LH.Artifacts} artifacts
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
/* eslint-disable no-unused-vars */ // TODO: remove once implemented.
|
|
2
|
-
|
|
3
1
|
/**
|
|
4
2
|
* @license
|
|
5
3
|
* Copyright 2025 Google LLC
|
|
@@ -10,11 +8,14 @@ import {UIStrings} from '@paulirish/trace_engine/models/trace/insights/Duplicate
|
|
|
10
8
|
|
|
11
9
|
import {Audit} from '../audit.js';
|
|
12
10
|
import * as i18n from '../../lib/i18n/i18n.js';
|
|
13
|
-
import {adaptInsightToAuditProduct
|
|
11
|
+
import {adaptInsightToAuditProduct} from './insight-audit.js';
|
|
14
12
|
|
|
15
13
|
// eslint-disable-next-line max-len
|
|
16
14
|
const str_ = i18n.createIcuMessageFn('node_modules/@paulirish/trace_engine/models/trace/insights/DuplicatedJavaScript.js', UIStrings);
|
|
17
15
|
|
|
16
|
+
/** @typedef {LH.Audit.Details.TableItem & {source: string, subItems: {type: 'subitems', items: SubItem[]}}} Item */
|
|
17
|
+
/** @typedef {{url: string, sourceTransferBytes: number|LH.Audit.Details.TextValue}} SubItem */
|
|
18
|
+
|
|
18
19
|
class DuplicatedJavaScriptInsight extends Audit {
|
|
19
20
|
/**
|
|
20
21
|
* @return {LH.Audit.Meta}
|
|
@@ -25,8 +26,9 @@ class DuplicatedJavaScriptInsight extends Audit {
|
|
|
25
26
|
title: str_(UIStrings.title),
|
|
26
27
|
failureTitle: str_(UIStrings.title),
|
|
27
28
|
description: str_(UIStrings.description),
|
|
28
|
-
guidanceLevel:
|
|
29
|
-
requiredArtifacts: ['
|
|
29
|
+
guidanceLevel: 2,
|
|
30
|
+
requiredArtifacts: ['Trace', 'SourceMaps'],
|
|
31
|
+
replacesAudits: ['duplicated-javascript'],
|
|
30
32
|
};
|
|
31
33
|
}
|
|
32
34
|
|
|
@@ -36,16 +38,41 @@ class DuplicatedJavaScriptInsight extends Audit {
|
|
|
36
38
|
* @return {Promise<LH.Audit.Product>}
|
|
37
39
|
*/
|
|
38
40
|
static async audit(artifacts, context) {
|
|
39
|
-
// TODO: implement.
|
|
40
41
|
return adaptInsightToAuditProduct(artifacts, context, 'DuplicatedJavaScript', (insight) => {
|
|
41
42
|
/** @type {LH.Audit.Details.Table['headings']} */
|
|
42
43
|
const headings = [
|
|
43
44
|
/* eslint-disable max-len */
|
|
45
|
+
{key: 'source', valueType: 'code', subItemsHeading: {key: 'url', valueType: 'url'}, label: str_(i18n.UIStrings.columnSource)},
|
|
46
|
+
{key: 'wastedBytes', valueType: 'bytes', subItemsHeading: {key: 'sourceTransferBytes'}, granularity: 10, label: str_(UIStrings.columnDuplicatedBytes)},
|
|
44
47
|
/* eslint-enable max-len */
|
|
45
48
|
];
|
|
46
|
-
|
|
47
|
-
const
|
|
48
|
-
|
|
49
|
+
|
|
50
|
+
const entries = [...insight.duplicationGroupedByNodeModules.entries()].slice(0, 10);
|
|
51
|
+
|
|
52
|
+
/** @type {Item[]} */
|
|
53
|
+
const items = entries.map(([source, data]) => {
|
|
54
|
+
/** @type {Item} */
|
|
55
|
+
const item = {
|
|
56
|
+
source,
|
|
57
|
+
wastedBytes: data.estimatedDuplicateBytes,
|
|
58
|
+
subItems: {
|
|
59
|
+
type: 'subitems',
|
|
60
|
+
items: [],
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
for (const [index, {script, attributedSize}] of data.duplicates.entries()) {
|
|
65
|
+
/** @type {SubItem} */
|
|
66
|
+
const subItem = {
|
|
67
|
+
url: script.url ?? '',
|
|
68
|
+
sourceTransferBytes: index === 0 ? {type: 'text', value: '--'} : attributedSize,
|
|
69
|
+
};
|
|
70
|
+
item.subItems.items.push(subItem);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return item;
|
|
74
|
+
});
|
|
75
|
+
|
|
49
76
|
return Audit.makeTableDetails(headings, items);
|
|
50
77
|
});
|
|
51
78
|
}
|
|
@@ -24,7 +24,7 @@ class FontDisplayInsight extends Audit {
|
|
|
24
24
|
failureTitle: str_(UIStrings.title),
|
|
25
25
|
description: str_(UIStrings.description),
|
|
26
26
|
guidanceLevel: 3,
|
|
27
|
-
requiredArtifacts: ['
|
|
27
|
+
requiredArtifacts: ['Trace', 'TraceElements', 'SourceMaps'],
|
|
28
28
|
replacesAudits: ['font-display'],
|
|
29
29
|
};
|
|
30
30
|
}
|
|
@@ -24,7 +24,7 @@ class ForcedReflowInsight extends Audit {
|
|
|
24
24
|
failureTitle: str_(UIStrings.title),
|
|
25
25
|
description: str_(UIStrings.description),
|
|
26
26
|
guidanceLevel: 3,
|
|
27
|
-
requiredArtifacts: ['
|
|
27
|
+
requiredArtifacts: ['Trace', 'TraceElements', 'SourceMaps'],
|
|
28
28
|
};
|
|
29
29
|
}
|
|
30
30
|
|
|
@@ -29,7 +29,7 @@ class ImageDeliveryInsight extends Audit {
|
|
|
29
29
|
failureTitle: str_(UIStrings.title),
|
|
30
30
|
description: str_(UIStrings.description),
|
|
31
31
|
guidanceLevel: 3,
|
|
32
|
-
requiredArtifacts: ['
|
|
32
|
+
requiredArtifacts: ['Trace', 'TraceElements', 'SourceMaps'],
|
|
33
33
|
replacesAudits: [
|
|
34
34
|
'modern-image-formats',
|
|
35
35
|
'uses-optimized-images',
|
|
@@ -1,23 +1,25 @@
|
|
|
1
|
+
export type CreateDetailsExtras = {
|
|
2
|
+
insights: import("@paulirish/trace_engine/models/trace/insights/types.js").InsightSet;
|
|
3
|
+
parsedTrace: LH.Artifacts.TraceEngineResult["data"];
|
|
4
|
+
};
|
|
5
|
+
/**
|
|
6
|
+
* @typedef CreateDetailsExtras
|
|
7
|
+
* @property {import('@paulirish/trace_engine/models/trace/insights/types.js').InsightSet} insights
|
|
8
|
+
* @property {LH.Artifacts.TraceEngineResult['data']} parsedTrace
|
|
9
|
+
*/
|
|
1
10
|
/**
|
|
2
11
|
* @param {LH.Artifacts} artifacts
|
|
3
12
|
* @param {LH.Audit.Context} context
|
|
4
13
|
* @param {T} insightName
|
|
5
|
-
* @param {(insight: import('@paulirish/trace_engine/models/trace/insights/types.js').InsightModels[T]) => LH.Audit.Details|undefined} createDetails
|
|
14
|
+
* @param {(insight: import('@paulirish/trace_engine/models/trace/insights/types.js').InsightModels[T], extras: CreateDetailsExtras) => LH.Audit.Details|undefined} createDetails
|
|
6
15
|
* @template {keyof import('@paulirish/trace_engine/models/trace/insights/types.js').InsightModelsType} T
|
|
7
16
|
* @return {Promise<LH.Audit.Product>}
|
|
8
17
|
*/
|
|
9
|
-
export function adaptInsightToAuditProduct<T extends keyof import("@paulirish/trace_engine/models/trace/insights/types.js").InsightModelsType>(artifacts: LH.Artifacts, context: LH.Audit.Context, insightName: T, createDetails: (insight: import("@paulirish/trace_engine/models/trace/insights/types.js").InsightModels[T]) => LH.Audit.Details | undefined): Promise<LH.Audit.Product>;
|
|
18
|
+
export function adaptInsightToAuditProduct<T extends keyof import("@paulirish/trace_engine/models/trace/insights/types.js").InsightModelsType>(artifacts: LH.Artifacts, context: LH.Audit.Context, insightName: T, createDetails: (insight: import("@paulirish/trace_engine/models/trace/insights/types.js").InsightModels[T], extras: CreateDetailsExtras) => LH.Audit.Details | undefined): Promise<LH.Audit.Product>;
|
|
10
19
|
/**
|
|
11
20
|
* @param {LH.Artifacts.TraceElement[]} traceElements
|
|
12
21
|
* @param {number|null|undefined} nodeId
|
|
13
22
|
* @return {LH.Audit.Details.NodeValue|undefined}
|
|
14
23
|
*/
|
|
15
24
|
export function makeNodeItemForNodeId(traceElements: LH.Artifacts.TraceElement[], nodeId: number | null | undefined): LH.Audit.Details.NodeValue | undefined;
|
|
16
|
-
/**
|
|
17
|
-
* @param {LH.Artifacts.TraceElement[]} traceElements
|
|
18
|
-
* @param {number|null|undefined} nodeId
|
|
19
|
-
* @param {LH.IcuMessage|string} label
|
|
20
|
-
* @return {LH.Audit.Details.Table|undefined}
|
|
21
|
-
*/
|
|
22
|
-
export function maybeMakeNodeElementTable(traceElements: LH.Artifacts.TraceElement[], nodeId: number | null | undefined, label: LH.IcuMessage | string): LH.Audit.Details.Table | undefined;
|
|
23
25
|
//# sourceMappingURL=insight-audit.d.ts.map
|
|
@@ -9,35 +9,45 @@ import {NO_NAVIGATION} from '@paulirish/trace_engine/models/trace/types/TraceEve
|
|
|
9
9
|
import {ProcessedTrace} from '../../computed/processed-trace.js';
|
|
10
10
|
import {TraceEngineResult} from '../../computed/trace-engine-result.js';
|
|
11
11
|
import {Audit} from '../audit.js';
|
|
12
|
+
import * as i18n from '../../lib/i18n/i18n.js';
|
|
13
|
+
|
|
14
|
+
const str_ = i18n.createIcuMessageFn(import.meta.url, {});
|
|
12
15
|
|
|
13
16
|
/**
|
|
14
17
|
* @param {LH.Artifacts} artifacts
|
|
15
18
|
* @param {LH.Audit.Context} context
|
|
16
|
-
* @return {Promise<import('@paulirish/trace_engine/models/trace/insights/types.js').InsightSet|undefined>}
|
|
19
|
+
* @return {Promise<{insights: import('@paulirish/trace_engine/models/trace/insights/types.js').InsightSet|undefined, parsedTrace: LH.Artifacts.TraceEngineResult['data']}>}
|
|
17
20
|
*/
|
|
18
21
|
async function getInsightSet(artifacts, context) {
|
|
19
22
|
const settings = context.settings;
|
|
20
|
-
const trace = artifacts.
|
|
23
|
+
const trace = artifacts.Trace;
|
|
21
24
|
const processedTrace = await ProcessedTrace.request(trace, context);
|
|
22
25
|
const SourceMaps = artifacts.SourceMaps;
|
|
23
26
|
const traceEngineResult = await TraceEngineResult.request({trace, settings, SourceMaps}, context);
|
|
24
27
|
|
|
25
28
|
const navigationId = processedTrace.timeOriginEvt.args.data?.navigationId;
|
|
26
29
|
const key = navigationId ?? NO_NAVIGATION;
|
|
30
|
+
const insights = traceEngineResult.insights.get(key);
|
|
27
31
|
|
|
28
|
-
return traceEngineResult.
|
|
32
|
+
return {insights, parsedTrace: traceEngineResult.data};
|
|
29
33
|
}
|
|
30
34
|
|
|
35
|
+
/**
|
|
36
|
+
* @typedef CreateDetailsExtras
|
|
37
|
+
* @property {import('@paulirish/trace_engine/models/trace/insights/types.js').InsightSet} insights
|
|
38
|
+
* @property {LH.Artifacts.TraceEngineResult['data']} parsedTrace
|
|
39
|
+
*/
|
|
40
|
+
|
|
31
41
|
/**
|
|
32
42
|
* @param {LH.Artifacts} artifacts
|
|
33
43
|
* @param {LH.Audit.Context} context
|
|
34
44
|
* @param {T} insightName
|
|
35
|
-
* @param {(insight: import('@paulirish/trace_engine/models/trace/insights/types.js').InsightModels[T]) => LH.Audit.Details|undefined} createDetails
|
|
45
|
+
* @param {(insight: import('@paulirish/trace_engine/models/trace/insights/types.js').InsightModels[T], extras: CreateDetailsExtras) => LH.Audit.Details|undefined} createDetails
|
|
36
46
|
* @template {keyof import('@paulirish/trace_engine/models/trace/insights/types.js').InsightModelsType} T
|
|
37
47
|
* @return {Promise<LH.Audit.Product>}
|
|
38
48
|
*/
|
|
39
49
|
async function adaptInsightToAuditProduct(artifacts, context, insightName, createDetails) {
|
|
40
|
-
const insights = await getInsightSet(artifacts, context);
|
|
50
|
+
const {insights, parsedTrace} = await getInsightSet(artifacts, context);
|
|
41
51
|
if (!insights) {
|
|
42
52
|
return {
|
|
43
53
|
scoreDisplayMode: Audit.SCORING_MODES.NOT_APPLICABLE,
|
|
@@ -54,7 +64,10 @@ async function adaptInsightToAuditProduct(artifacts, context, insightName, creat
|
|
|
54
64
|
};
|
|
55
65
|
}
|
|
56
66
|
|
|
57
|
-
const details = createDetails(insight
|
|
67
|
+
const details = createDetails(insight, {
|
|
68
|
+
parsedTrace,
|
|
69
|
+
insights,
|
|
70
|
+
});
|
|
58
71
|
if (!details || (details.type === 'table' && details.headings.length === 0)) {
|
|
59
72
|
return {
|
|
60
73
|
scoreDisplayMode: Audit.SCORING_MODES.NOT_APPLICABLE,
|
|
@@ -73,23 +86,30 @@ async function adaptInsightToAuditProduct(artifacts, context, insightName, creat
|
|
|
73
86
|
metricSavings = {...metricSavings, LCP: /** @type {any} */ (0)};
|
|
74
87
|
}
|
|
75
88
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
89
|
+
// TODO: consider adding a `estimatedSavingsText` to InsightModel, which can capture
|
|
90
|
+
// the exact i18n string used by RPP; and include the same est. timing savings.
|
|
91
|
+
let displayValue;
|
|
92
|
+
if (insight.wastedBytes) {
|
|
93
|
+
displayValue = str_(i18n.UIStrings.displayValueByteSavings, {wastedBytes: insight.wastedBytes});
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
let score;
|
|
97
|
+
let scoreDisplayMode;
|
|
98
|
+
if (insight.state === 'fail' || insight.state === 'pass') {
|
|
99
|
+
score = insight.state === 'fail' ? 0 : 1;
|
|
100
|
+
scoreDisplayMode =
|
|
101
|
+
insight.metricSavings ? Audit.SCORING_MODES.METRIC_SAVINGS : Audit.SCORING_MODES.NUMERIC;
|
|
102
|
+
} else {
|
|
103
|
+
score = null;
|
|
104
|
+
scoreDisplayMode = Audit.SCORING_MODES.INFORMATIVE;
|
|
85
105
|
}
|
|
86
106
|
|
|
87
107
|
return {
|
|
88
|
-
scoreDisplayMode
|
|
89
|
-
insight.metricSavings ? Audit.SCORING_MODES.METRIC_SAVINGS : Audit.SCORING_MODES.NUMERIC,
|
|
108
|
+
scoreDisplayMode,
|
|
90
109
|
score,
|
|
91
110
|
metricSavings,
|
|
92
111
|
warnings: insight.warnings,
|
|
112
|
+
displayValue,
|
|
93
113
|
details,
|
|
94
114
|
};
|
|
95
115
|
}
|
|
@@ -114,25 +134,7 @@ function makeNodeItemForNodeId(traceElements, nodeId) {
|
|
|
114
134
|
return Audit.makeNodeItem(node);
|
|
115
135
|
}
|
|
116
136
|
|
|
117
|
-
/**
|
|
118
|
-
* @param {LH.Artifacts.TraceElement[]} traceElements
|
|
119
|
-
* @param {number|null|undefined} nodeId
|
|
120
|
-
* @param {LH.IcuMessage|string} label
|
|
121
|
-
* @return {LH.Audit.Details.Table|undefined}
|
|
122
|
-
*/
|
|
123
|
-
function maybeMakeNodeElementTable(traceElements, nodeId, label) {
|
|
124
|
-
const node = makeNodeItemForNodeId(traceElements, nodeId);
|
|
125
|
-
if (!node) {
|
|
126
|
-
return;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
return Audit.makeTableDetails([
|
|
130
|
-
{key: 'node', valueType: 'node', label},
|
|
131
|
-
], [{node}]);
|
|
132
|
-
}
|
|
133
|
-
|
|
134
137
|
export {
|
|
135
138
|
adaptInsightToAuditProduct,
|
|
136
139
|
makeNodeItemForNodeId,
|
|
137
|
-
maybeMakeNodeElementTable,
|
|
138
140
|
};
|
|
@@ -8,7 +8,7 @@ import {UIStrings} from '@paulirish/trace_engine/models/trace/insights/Interacti
|
|
|
8
8
|
|
|
9
9
|
import {Audit} from '../audit.js';
|
|
10
10
|
import * as i18n from '../../lib/i18n/i18n.js';
|
|
11
|
-
import {adaptInsightToAuditProduct,
|
|
11
|
+
import {adaptInsightToAuditProduct, makeNodeItemForNodeId} from './insight-audit.js';
|
|
12
12
|
|
|
13
13
|
// eslint-disable-next-line max-len
|
|
14
14
|
const str_ = i18n.createIcuMessageFn('node_modules/@paulirish/trace_engine/models/trace/insights/InteractionToNextPaint.js', UIStrings);
|
|
@@ -24,7 +24,7 @@ class InteractionToNextPaintInsight extends Audit {
|
|
|
24
24
|
failureTitle: str_(UIStrings.title),
|
|
25
25
|
description: str_(UIStrings.description),
|
|
26
26
|
guidanceLevel: 3,
|
|
27
|
-
requiredArtifacts: ['
|
|
27
|
+
requiredArtifacts: ['Trace', 'TraceElements', 'SourceMaps'],
|
|
28
28
|
replacesAudits: ['work-during-interaction'],
|
|
29
29
|
};
|
|
30
30
|
}
|
|
@@ -58,11 +58,8 @@ class InteractionToNextPaintInsight extends Audit {
|
|
|
58
58
|
];
|
|
59
59
|
|
|
60
60
|
return Audit.makeListDetails([
|
|
61
|
-
maybeMakeNodeElementTable(
|
|
62
|
-
artifacts.TraceElements,
|
|
63
|
-
event.args.data.beginEvent.args.data.nodeId,
|
|
64
|
-
str_(i18n.UIStrings.columnElement)),
|
|
65
61
|
Audit.makeTableDetails(headings, items),
|
|
62
|
+
makeNodeItemForNodeId(artifacts.TraceElements, event.args.data.beginEvent.args.data.nodeId),
|
|
66
63
|
].filter(table => !!table));
|
|
67
64
|
});
|
|
68
65
|
}
|
|
@@ -8,7 +8,7 @@ import {UIStrings} from '@paulirish/trace_engine/models/trace/insights/LCPDiscov
|
|
|
8
8
|
|
|
9
9
|
import {Audit} from '../audit.js';
|
|
10
10
|
import * as i18n from '../../lib/i18n/i18n.js';
|
|
11
|
-
import {adaptInsightToAuditProduct} from './insight-audit.js';
|
|
11
|
+
import {adaptInsightToAuditProduct, makeNodeItemForNodeId} from './insight-audit.js';
|
|
12
12
|
|
|
13
13
|
// eslint-disable-next-line max-len
|
|
14
14
|
const str_ = i18n.createIcuMessageFn('node_modules/@paulirish/trace_engine/models/trace/insights/LCPDiscovery.js', UIStrings);
|
|
@@ -24,7 +24,7 @@ class LCPDiscoveryInsight extends Audit {
|
|
|
24
24
|
failureTitle: str_(UIStrings.title),
|
|
25
25
|
description: str_(UIStrings.description),
|
|
26
26
|
guidanceLevel: 3,
|
|
27
|
-
requiredArtifacts: ['
|
|
27
|
+
requiredArtifacts: ['Trace', 'TraceElements', 'SourceMaps'],
|
|
28
28
|
replacesAudits: ['prioritize-lcp-image', 'lcp-lazy-loaded'],
|
|
29
29
|
};
|
|
30
30
|
}
|
|
@@ -40,7 +40,10 @@ class LCPDiscoveryInsight extends Audit {
|
|
|
40
40
|
return;
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
return Audit.
|
|
43
|
+
return Audit.makeListDetails([
|
|
44
|
+
Audit.makeChecklistDetails(insight.checklist),
|
|
45
|
+
makeNodeItemForNodeId(artifacts.TraceElements, insight.lcpEvent?.args.data?.nodeId),
|
|
46
|
+
].filter(d => !!d));
|
|
44
47
|
});
|
|
45
48
|
}
|
|
46
49
|
}
|
|
@@ -8,7 +8,7 @@ import {UIStrings} from '@paulirish/trace_engine/models/trace/insights/LCPPhases
|
|
|
8
8
|
|
|
9
9
|
import {Audit} from '../audit.js';
|
|
10
10
|
import * as i18n from '../../lib/i18n/i18n.js';
|
|
11
|
-
import {adaptInsightToAuditProduct,
|
|
11
|
+
import {adaptInsightToAuditProduct, makeNodeItemForNodeId} from './insight-audit.js';
|
|
12
12
|
|
|
13
13
|
// eslint-disable-next-line max-len
|
|
14
14
|
const str_ = i18n.createIcuMessageFn('node_modules/@paulirish/trace_engine/models/trace/insights/LCPPhases.js', UIStrings);
|
|
@@ -24,7 +24,7 @@ class LCPPhasesInsight extends Audit {
|
|
|
24
24
|
failureTitle: str_(UIStrings.title),
|
|
25
25
|
description: str_(UIStrings.description),
|
|
26
26
|
guidanceLevel: 3,
|
|
27
|
-
requiredArtifacts: ['
|
|
27
|
+
requiredArtifacts: ['Trace', 'TraceElements', 'SourceMaps'],
|
|
28
28
|
replacesAudits: ['largest-contentful-paint-element'],
|
|
29
29
|
};
|
|
30
30
|
}
|
|
@@ -74,11 +74,8 @@ class LCPPhasesInsight extends Audit {
|
|
|
74
74
|
}
|
|
75
75
|
|
|
76
76
|
return Audit.makeListDetails([
|
|
77
|
-
maybeMakeNodeElementTable(
|
|
78
|
-
artifacts.TraceElements,
|
|
79
|
-
insight.lcpEvent?.args.data?.nodeId,
|
|
80
|
-
str_(i18n.UIStrings.columnElement)),
|
|
81
77
|
LCPPhasesInsight.makePhaseTable(insight.phases),
|
|
78
|
+
makeNodeItemForNodeId(artifacts.TraceElements, insight.lcpEvent?.args.data?.nodeId),
|
|
82
79
|
].filter(table => table !== undefined));
|
|
83
80
|
});
|
|
84
81
|
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export default LegacyJavaScriptInsight;
|
|
2
|
+
export type Item = LH.Audit.Details.TableItem & {
|
|
3
|
+
subItems: {
|
|
4
|
+
type: "subitems";
|
|
5
|
+
items: SubItem[];
|
|
6
|
+
};
|
|
7
|
+
};
|
|
8
|
+
export type SubItem = {
|
|
9
|
+
signal: string;
|
|
10
|
+
location: LH.Audit.Details.SourceLocationValue;
|
|
11
|
+
};
|
|
12
|
+
/** @typedef {LH.Audit.Details.TableItem & {subItems: {type: 'subitems', items: SubItem[]}}} Item */
|
|
13
|
+
/** @typedef {{signal: string, location: LH.Audit.Details.SourceLocationValue}} SubItem */
|
|
14
|
+
declare class LegacyJavaScriptInsight extends Audit {
|
|
15
|
+
/**
|
|
16
|
+
* @param {LH.Artifacts} artifacts
|
|
17
|
+
* @param {LH.Audit.Context} context
|
|
18
|
+
* @return {Promise<LH.Audit.Product>}
|
|
19
|
+
*/
|
|
20
|
+
static audit(artifacts: LH.Artifacts, context: LH.Audit.Context): Promise<LH.Audit.Product>;
|
|
21
|
+
}
|
|
22
|
+
import { Audit } from '../audit.js';
|
|
23
|
+
//# sourceMappingURL=legacy-javascript-insight.d.ts.map
|