lighthouse 11.1.0-dev.20230919 → 11.1.0-dev.20230921

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/bin.js CHANGED
@@ -124,6 +124,7 @@ async function begin() {
124
124
  await Sentry.init({
125
125
  url: urlUnderTest,
126
126
  flags: cliFlags,
127
+ config,
127
128
  environmentData: {
128
129
  serverName: 'redacted', // prevent sentry from using hostname
129
130
  environment: isDev() ? 'development' : 'production',
@@ -8,11 +8,14 @@
8
8
  * @fileoverview Audit a page to show a breakdown of execution timings on the main thread
9
9
  */
10
10
 
11
+ import log from 'lighthouse-logger';
11
12
 
12
13
  import {Audit} from './audit.js';
13
14
  import {taskGroups} from '../lib/tracehouse/task-groups.js';
14
15
  import * as i18n from '../lib/i18n/i18n.js';
15
16
  import {MainThreadTasks} from '../computed/main-thread-tasks.js';
17
+ import {TotalBlockingTime} from '../computed/metrics/total-blocking-time.js';
18
+ import {Sentry} from '../lib/sentry.js';
16
19
 
17
20
  const UIStrings = {
18
21
  /** Title of a diagnostic audit that provides detail on the main thread work the browser did to load the page. This descriptive title is shown to users when the amount is acceptable and no user action is required. */
@@ -43,7 +46,7 @@ class MainThreadWorkBreakdown extends Audit {
43
46
  description: str_(UIStrings.description),
44
47
  scoreDisplayMode: Audit.SCORING_MODES.NUMERIC,
45
48
  guidanceLevel: 1,
46
- requiredArtifacts: ['traces'],
49
+ requiredArtifacts: ['traces', 'devtoolsLogs', 'URL', 'GatherContext'],
47
50
  };
48
51
  }
49
52
 
@@ -83,6 +86,19 @@ class MainThreadWorkBreakdown extends Audit {
83
86
  const settings = context.settings || {};
84
87
  const trace = artifacts.traces[MainThreadWorkBreakdown.DEFAULT_PASS];
85
88
 
89
+ let tbtSavings = 0;
90
+ try {
91
+ const metricComputationData = Audit.makeMetricComputationDataInput(artifacts, context);
92
+ const tbtResult = await TotalBlockingTime.request(metricComputationData, context);
93
+ tbtSavings = tbtResult.timing;
94
+ } catch (err) {
95
+ Sentry.captureException(err, {
96
+ tags: {audit: this.meta.id},
97
+ level: 'error',
98
+ });
99
+ log.error(this.meta.id, err.message);
100
+ }
101
+
86
102
  const tasks = await MainThreadTasks.request(trace, context);
87
103
  const multiplier = settings.throttlingMethod === 'simulate' ?
88
104
  settings.throttling.cpuSlowdownMultiplier : 1;
@@ -129,6 +145,9 @@ class MainThreadWorkBreakdown extends Audit {
129
145
  numericUnit: 'millisecond',
130
146
  displayValue: str_(i18n.UIStrings.seconds, {timeInMs: totalExecutionTime}),
131
147
  details: tableDetails,
148
+ metricSavings: {
149
+ TBT: tbtSavings,
150
+ },
132
151
  };
133
152
  }
134
153
  }
@@ -62,6 +62,11 @@ async function collectTagsThatBlockFirstPaint() {
62
62
  /** @type {Array<LinkTag>} */
63
63
  const linkTags = [...document.querySelectorAll('link')]
64
64
  .filter(linkTag => {
65
+ // Ignore malformed links with no href (e.g. `<link rel="stylesheet" href="">`)
66
+ // The resolved `linkTag.href` will be the main document, but the main document
67
+ // should never be render blocking.
68
+ if (!linkTag.getAttribute('href')) return false;
69
+
65
70
  // Filter stylesheet/HTML imports that block rendering.
66
71
  // https://www.igvita.com/2012/06/14/debunking-responsive-css-performance-myths/
67
72
  // https://www.w3.org/TR/html-imports/#dfn-import-async-attribute
@@ -20,11 +20,12 @@ export type NodeOptions = import('@sentry/node').NodeOptions;
20
20
  export type Severity = import('@sentry/node').Severity;
21
21
  /**
22
22
  * When called, replaces noops with actual Sentry implementation.
23
- * @param {{url: string, flags: LH.CliFlags, environmentData: NodeOptions}} opts
23
+ * @param {{url: string, flags: LH.CliFlags, config?: LH.Config, environmentData: NodeOptions}} opts
24
24
  */
25
25
  declare function init(opts: {
26
26
  url: string;
27
27
  flags: LH.CliFlags;
28
+ config?: LH.Config;
28
29
  environmentData: NodeOptions;
29
30
  }): Promise<void>;
30
31
  declare function noop(): void;
@@ -6,6 +6,8 @@
6
6
 
7
7
  import log from 'lighthouse-logger';
8
8
 
9
+ import {initializeConfig} from '../config/config.js';
10
+
9
11
  /** @typedef {import('@sentry/node').Breadcrumb} Breadcrumb */
10
12
  /** @typedef {import('@sentry/node').NodeClient} NodeClient */
11
13
  /** @typedef {import('@sentry/node').NodeOptions} NodeOptions */
@@ -16,12 +18,6 @@ const SENTRY_URL = 'https://a6bb0da87ee048cc9ae2a345fc09ab2e:63a7029f46f74265981
16
18
  // Per-run chance of capturing errors (if enabled).
17
19
  const SAMPLE_RATE = 0.01;
18
20
 
19
- /** @type {Array<{pattern: RegExp, rate: number}>} */
20
- const SAMPLED_ERRORS = [
21
- // Error code based sampling. Delete if still unused after 2019-01-01.
22
- // e.g.: {pattern: /No.*node with given id/, rate: 0.01},
23
- ];
24
-
25
21
  const noop = () => { };
26
22
 
27
23
  /**
@@ -45,7 +41,7 @@ const sentryDelegate = {
45
41
 
46
42
  /**
47
43
  * When called, replaces noops with actual Sentry implementation.
48
- * @param {{url: string, flags: LH.CliFlags, environmentData: NodeOptions}} opts
44
+ * @param {{url: string, flags: LH.CliFlags, config?: LH.Config, environmentData: NodeOptions}} opts
49
45
  */
50
46
  async function init(opts) {
51
47
  // If error reporting is disabled, leave the functions as a noop
@@ -65,12 +61,26 @@ async function init(opts) {
65
61
  dsn: SENTRY_URL,
66
62
  });
67
63
 
64
+ /** @type {LH.Config.Settings | LH.CliFlags} */
65
+ let settings = opts.flags;
66
+ try {
67
+ const {resolvedConfig} = await initializeConfig('navigation', opts.config, opts.flags);
68
+ settings = resolvedConfig.settings;
69
+ } catch {
70
+ // The config failed validation (note - probably, we don't use a specific error type for that).
71
+ // The actual core lighthouse library will handle this error accordingly. As we are only using this
72
+ // for meta data, we can ignore here.
73
+ }
74
+ const baseTags = {
75
+ channel: settings.channel,
76
+ formFactor: settings.formFactor,
77
+ throttlingMethod: settings.throttlingMethod,
78
+ };
79
+ Sentry.setTags(baseTags);
80
+
68
81
  const extras = {
69
- ...opts.flags.throttling,
70
- channel: opts.flags.channel || 'cli',
82
+ ...settings.throttling,
71
83
  url: opts.url,
72
- formFactor: opts.flags.formFactor,
73
- throttlingMethod: opts.flags.throttlingMethod,
74
84
  };
75
85
  Sentry.setExtras(extras);
76
86
 
@@ -103,10 +113,6 @@ async function init(opts) {
103
113
  sentryExceptionCache.set(key, true);
104
114
  }
105
115
 
106
- // Sample known errors that occur at a high frequency.
107
- const sampledErrorMatch = SAMPLED_ERRORS.find(sample => sample.pattern.test(err.message));
108
- if (sampledErrorMatch && sampledErrorMatch.rate <= Math.random()) return;
109
-
110
116
  // @ts-expect-error - properties added to protocol method LighthouseErrors.
111
117
  if (err.protocolMethod) {
112
118
  // Protocol errors all share same stack trace, so add more to fingerprint
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "lighthouse",
3
3
  "type": "module",
4
- "version": "11.1.0-dev.20230919",
4
+ "version": "11.1.0-dev.20230921",
5
5
  "description": "Automated auditing, performance metrics, and best practices for the web.",
6
6
  "main": "./core/index.js",
7
7
  "bin": {