lighthouse 9.5.0-dev.20220823 → 9.5.0-dev.20220824

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.
@@ -139,11 +139,17 @@ function purpleify(str) {
139
139
  */
140
140
  function convertToLegacyConfig(configJson) {
141
141
  if (!configJson) return configJson;
142
- if (!configJson.navigations) return configJson;
143
142
 
144
143
  return {
145
144
  ...configJson,
146
- passes: configJson.navigations.map(nav => ({...nav, passName: nav.id.concat('Pass')})),
145
+ passes: [{
146
+ passName: 'defaultPass',
147
+ pauseAfterFcpMs: configJson.settings?.pauseAfterFcpMs,
148
+ pauseAfterLoadMs: configJson.settings?.pauseAfterLoadMs,
149
+ networkQuietThresholdMs: configJson.settings?.networkQuietThresholdMs,
150
+ cpuQuietThresholdMs: configJson.settings?.cpuQuietThresholdMs,
151
+ blankPage: configJson.settings?.blankPage,
152
+ }],
147
153
  };
148
154
  }
149
155
 
@@ -95,6 +95,10 @@ const defaultSettings = {
95
95
  output: 'json',
96
96
  maxWaitForFcp: 30 * 1000,
97
97
  maxWaitForLoad: 45 * 1000,
98
+ pauseAfterFcpMs: 1000,
99
+ pauseAfterLoadMs: 1000,
100
+ networkQuietThresholdMs: 1000,
101
+ cpuQuietThresholdMs: 1000,
98
102
 
99
103
  formFactor: 'mobile',
100
104
  throttling: throttling.mobileSlow4G,
@@ -107,6 +111,8 @@ const defaultSettings = {
107
111
  disableStorageReset: false,
108
112
  debugNavigation: false,
109
113
  channel: 'node',
114
+ skipAboutBlank: false,
115
+ blankPage: 'about:blank',
110
116
 
111
117
  // the following settings have no defaults but we still want ensure that `key in settings`
112
118
  // in config will work in a typechecked way
@@ -119,7 +125,6 @@ const defaultSettings = {
119
125
  onlyAudits: null,
120
126
  onlyCategories: null,
121
127
  skipAudits: null,
122
- skipAboutBlank: false,
123
128
  };
124
129
 
125
130
  /** @type {LH.Config.Pass} */
@@ -221,62 +221,6 @@ const defaultConfig = {
221
221
  // FullPageScreenshot comes at the very end so all other node analysis is captured.
222
222
  {id: artifacts.FullPageScreenshot, gatherer: 'full-page-screenshot'},
223
223
  ],
224
- navigations: [
225
- {
226
- id: 'default',
227
- pauseAfterFcpMs: 1000,
228
- pauseAfterLoadMs: 1000,
229
- networkQuietThresholdMs: 1000,
230
- cpuQuietThresholdMs: 1000,
231
- artifacts: [
232
- // Artifacts which can be depended on come first.
233
- artifacts.DevtoolsLog,
234
- artifacts.Trace,
235
-
236
- artifacts.Accessibility,
237
- artifacts.AnchorElements,
238
- artifacts.CacheContents,
239
- artifacts.ConsoleMessages,
240
- artifacts.CSSUsage,
241
- artifacts.Doctype,
242
- artifacts.DOMStats,
243
- artifacts.EmbeddedContent,
244
- artifacts.FontSize,
245
- artifacts.Inputs,
246
- artifacts.GlobalListeners,
247
- artifacts.IFrameElements,
248
- artifacts.ImageElements,
249
- artifacts.InstallabilityErrors,
250
- artifacts.InspectorIssues,
251
- artifacts.JsUsage,
252
- artifacts.LinkElements,
253
- artifacts.MainDocumentContent,
254
- artifacts.MetaElements,
255
- artifacts.NetworkUserAgent,
256
- artifacts.OptimizedImages,
257
- artifacts.PasswordInputsWithPreventedPaste,
258
- artifacts.ResponseCompression,
259
- artifacts.RobotsTxt,
260
- artifacts.ServiceWorker,
261
- artifacts.ScriptElements,
262
- artifacts.Scripts,
263
- artifacts.SourceMaps,
264
- artifacts.Stacks,
265
- artifacts.TagsBlockingFirstPaint,
266
- artifacts.TapTargets,
267
- artifacts.TraceElements,
268
- artifacts.ViewportDimensions,
269
- artifacts.WebAppManifest,
270
-
271
- // Compat artifacts come last.
272
- artifacts.devtoolsLogs,
273
- artifacts.traces,
274
-
275
- // FullPageScreenshot comes at the very end so all other node analysis is captured.
276
- artifacts.FullPageScreenshot,
277
- ],
278
- },
279
- ],
280
224
  audits: [
281
225
  'is-on-https',
282
226
  'service-worker',
@@ -19,7 +19,6 @@ if (!legacyDefaultConfig.categories) {
19
19
 
20
20
  // These properties are ignored in Legacy navigations.
21
21
  delete legacyDefaultConfig.artifacts;
22
- delete legacyDefaultConfig.navigations;
23
22
 
24
23
  // These audits don't work in Legacy navigation mode so we remove them.
25
24
  const unsupportedAuditIds = [
@@ -78,7 +78,7 @@ function resolveExtensions(configJSON) {
78
78
  throw new Error('`lighthouse:default` is the only valid extension method.');
79
79
  }
80
80
 
81
- const {artifacts, navigations, ...extensionJSON} = configJSON;
81
+ const {artifacts, ...extensionJSON} = configJSON;
82
82
  const defaultClone = deepCloneConfigJson(defaultConfig);
83
83
  const mergedConfig = mergeConfigFragment(defaultClone, extensionJSON);
84
84
 
@@ -87,11 +87,6 @@ function resolveExtensions(configJSON) {
87
87
  artifacts,
88
88
  artifact => artifact.id
89
89
  );
90
- mergedConfig.navigations = mergeConfigFragmentArrayByKey(
91
- defaultClone.navigations,
92
- navigations,
93
- navigation => navigation.id
94
- );
95
90
 
96
91
  return mergedConfig;
97
92
  }
@@ -213,39 +208,33 @@ function overrideNavigationThrottlingWindows(navigation, settings) {
213
208
  }
214
209
 
215
210
  /**
216
- *
217
- * @param {LH.Config.NavigationJson[]|null|undefined} navigations
218
211
  * @param {LH.Config.AnyArtifactDefn[]|null|undefined} artifactDefns
219
212
  * @param {LH.Config.Settings} settings
220
213
  * @return {LH.Config.NavigationDefn[] | null}
221
214
  */
222
- function resolveNavigationsToDefns(navigations, artifactDefns, settings) {
223
- if (!navigations) return null;
224
- if (!artifactDefns) throw new Error('Cannot use navigations without defining artifacts');
215
+ function resolveFakeNavigations(artifactDefns, settings) {
216
+ if (!artifactDefns) return null;
225
217
 
226
218
  const status = {msg: 'Resolve navigation definitions', id: 'lh:config:resolveNavigationsToDefns'};
227
219
  log.time(status, 'verbose');
228
220
 
229
- const artifactsById = new Map(artifactDefns.map(defn => [defn.id, defn]));
230
-
231
- const navigationDefns = navigations.map(navigation => {
232
- const navigationWithDefaults = {...defaultNavigationConfig, ...navigation};
233
- const navId = navigationWithDefaults.id;
234
- const artifacts = navigationWithDefaults.artifacts.map(id => {
235
- const artifact = artifactsById.get(id);
236
- if (!artifact) throw new Error(`Unrecognized artifact "${id}" in navigation "${navId}"`);
237
- return artifact;
238
- });
221
+ const resolvedNavigation = {
222
+ ...defaultNavigationConfig,
223
+ artifacts: artifactDefns,
224
+ pauseAfterFcpMs: settings.pauseAfterFcpMs,
225
+ pauseAfterLoadMs: settings.pauseAfterLoadMs,
226
+ networkQuietThresholdMs: settings.networkQuietThresholdMs,
227
+ cpuQuietThresholdMs: settings.cpuQuietThresholdMs,
228
+ blankPage: settings.blankPage,
229
+ };
239
230
 
240
- const resolvedNavigation = {...navigationWithDefaults, artifacts};
241
- overrideNavigationThrottlingWindows(resolvedNavigation, settings);
242
- return resolvedNavigation;
243
- });
231
+ overrideNavigationThrottlingWindows(resolvedNavigation, settings);
244
232
 
245
- assertArtifactTopologicalOrder(navigationDefns);
233
+ const navigations = [resolvedNavigation];
234
+ assertArtifactTopologicalOrder(navigations);
246
235
 
247
236
  log.timeEnd(status);
248
- return navigationDefns;
237
+ return navigations;
249
238
  }
250
239
 
251
240
  /**
@@ -267,7 +256,8 @@ async function initializeConfig(gatherMode, configJSON, flags = {}) {
267
256
  overrideSettingsForGatherMode(settings, gatherMode);
268
257
 
269
258
  const artifacts = await resolveArtifactsToDefns(configWorkingCopy.artifacts, configDir);
270
- const navigations = resolveNavigationsToDefns(configWorkingCopy.navigations, artifacts, settings);
259
+
260
+ const navigations = resolveFakeNavigations(artifacts, settings);
271
261
 
272
262
  /** @type {LH.Config.FRConfig} */
273
263
  let config = {
@@ -4700,7 +4700,7 @@ function getAppsOrigin() {
4700
4700
  const isDev = new URLSearchParams(window.location.search).has('dev');
4701
4701
 
4702
4702
  if (isVercel) return `https://${window.location.host}/gh-pages`;
4703
- if (isDev) return 'http://localhost:8000';
4703
+ if (isDev) return 'http://localhost:7333';
4704
4704
  return 'https://googlechrome.github.io/lighthouse';
4705
4705
  }
4706
4706
 
@@ -183,7 +183,7 @@ class yt{constructor(e,t){this._document=e,this._lighthouseChannel="unknown",thi
183
183
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
184
184
  * See the License for the specific language governing permissions and
185
185
  * limitations under the License.
186
- */function Pt(){const e=window.location.host.endsWith(".vercel.app"),t=new URLSearchParams(window.location.search).has("dev");return e?`https://${window.location.host}/gh-pages`:t?"http://localhost:8000":"https://googlechrome.github.io/lighthouse"}function Rt(e){const t=e.generatedTime,n=e.fetchTime||t;return`${e.lighthouseVersion}-${e.finalUrl}-${n}`}async function Ut(e,t,n){const r=new URL(t),o=Boolean(window.CompressionStream);r.hash=await Dt.toBase64(JSON.stringify(e),{gzip:o}),o&&r.searchParams.set("gzip","1"),window.open(r.toString(),n)}async function It(e){const t="viewer-"+Rt(e);!function(e,t,n){const r=new URL(t).origin;window.addEventListener("message",(function t(n){n.origin===r&&o&&n.data.opened&&(o.postMessage(e,r),window.removeEventListener("message",t))}));const o=window.open(t,n)}({lhr:e},Pt()+"/viewer/",t)}
186
+ */function Pt(){const e=window.location.host.endsWith(".vercel.app"),t=new URLSearchParams(window.location.search).has("dev");return e?`https://${window.location.host}/gh-pages`:t?"http://localhost:7333":"https://googlechrome.github.io/lighthouse"}function Rt(e){const t=e.generatedTime,n=e.fetchTime||t;return`${e.lighthouseVersion}-${e.finalUrl}-${n}`}async function Ut(e,t,n){const r=new URL(t),o=Boolean(window.CompressionStream);r.hash=await Dt.toBase64(JSON.stringify(e),{gzip:o}),o&&r.searchParams.set("gzip","1"),window.open(r.toString(),n)}async function It(e){const t="viewer-"+Rt(e);!function(e,t,n){const r=new URL(t).origin;window.addEventListener("message",(function t(n){n.origin===r&&o&&n.data.opened&&(o.postMessage(e,r),window.removeEventListener("message",t))}));const o=window.open(t,n)}({lhr:e},Pt()+"/viewer/",t)}
187
187
  /**
188
188
  * @license Copyright 2021 The Lighthouse Authors. All Rights Reserved.
189
189
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
@@ -166,7 +166,7 @@ class c{constructor(e,t){this._document=e,this._lighthouseChannel="unknown",this
166
166
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
167
167
  * See the License for the specific language governing permissions and
168
168
  * limitations under the License.
169
- */function S(){const e=window.location.host.endsWith(".vercel.app"),t=new URLSearchParams(window.location.search).has("dev");return e?`https://${window.location.host}/gh-pages`:t?"http://localhost:8000":"https://googlechrome.github.io/lighthouse"}function C(e){const t=e.generatedTime,n=e.fetchTime||t;return`${e.lighthouseVersion}-${e.finalUrl}-${n}`}async function L(e,t,n){const r=new URL(t),o=Boolean(window.CompressionStream);r.hash=await z.toBase64(JSON.stringify(e),{gzip:o}),o&&r.searchParams.set("gzip","1"),window.open(r.toString(),n)}async function M(e){const t="viewer-"+C(e);!function(e,t,n){const r=new URL(t).origin;window.addEventListener("message",(function t(n){n.origin===r&&o&&n.data.opened&&(o.postMessage(e,r),window.removeEventListener("message",t))}));const o=window.open(t,n)}({lhr:e},S()+"/viewer/",t)}
169
+ */function S(){const e=window.location.host.endsWith(".vercel.app"),t=new URLSearchParams(window.location.search).has("dev");return e?`https://${window.location.host}/gh-pages`:t?"http://localhost:7333":"https://googlechrome.github.io/lighthouse"}function C(e){const t=e.generatedTime,n=e.fetchTime||t;return`${e.lighthouseVersion}-${e.finalUrl}-${n}`}async function L(e,t,n){const r=new URL(t),o=Boolean(window.CompressionStream);r.hash=await z.toBase64(JSON.stringify(e),{gzip:o}),o&&r.searchParams.set("gzip","1"),window.open(r.toString(),n)}async function M(e){const t="viewer-"+C(e);!function(e,t,n){const r=new URL(t).origin;window.addEventListener("message",(function t(n){n.origin===r&&o&&n.data.opened&&(o.postMessage(e,r),window.removeEventListener("message",t))}));const o=window.open(t,n)}({lhr:e},S()+"/viewer/",t)}
170
170
  /**
171
171
  * @license Copyright 2021 The Lighthouse Authors. All Rights Reserved.
172
172
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "lighthouse",
3
3
  "type": "module",
4
- "version": "9.5.0-dev.20220823",
4
+ "version": "9.5.0-dev.20220824",
5
5
  "description": "Automated auditing, performance metrics, and best practices for the web.",
6
6
  "main": "./core/index.js",
7
7
  "bin": {
@@ -88,8 +88,8 @@
88
88
  "compile-proto": "protoc --python_out=./ ./proto/lighthouse-result.proto && mv ./proto/*_pb2.py ./proto/scripts || (echo \"❌ Install protobuf ≥ 3.7.1 to compile the proto file.\" && false)",
89
89
  "build-proto-roundtrip": "mkdir -p .tmp && cross-env PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION_VERSION=2 python proto/scripts/json_roundtrip_via_proto.py",
90
90
  "static-server": "node cli/test/fixtures/static-server.js",
91
- "serve-dist": "cd dist && python3 -m http.server",
92
- "serve-gh-pages": "cd dist/gh-pages && python3 -m http.server",
91
+ "serve-dist": "cd dist && python3 -m http.server 7878",
92
+ "serve-gh-pages": "cd dist/gh-pages && python3 -m http.server 7333",
93
93
  "serve-treemap": "yarn serve-gh-pages",
94
94
  "serve-viewer": "yarn serve-gh-pages",
95
95
  "flow-report": "yarn build-report --flow && node ./core/scripts/build-test-flow-report.js"
package/readme.md CHANGED
@@ -352,6 +352,10 @@ This section details services that have integrated Lighthouse data. If you're wo
352
352
 
353
353
  * **[SpeedVitals](https://speedvitals.com)** - SpeedVitals is a Lighthouse powered tool to measure web performance across multiple devices and locations. It has various features like Layout Shift Visualization, Waterfall Chart, Field Data and Resource Graphs. SpeedVitals offers both free and paid plans.
354
354
 
355
+ * **[Lighthouse Metrics](https://lighthouse-metrics.com/)** - Lighthouse Metrics gives you global performance insights with a single test. You can also monitor your websites on a daily or hourly base. Lighthouse Metrics offers free global one-time tests and performance monitoring as a paid feature with a free 14-day trial.
356
+
357
+ * **[Auditzy](https://auditzy.com)** - Auditzy™ is a robust website auditing & monitoring tool which lets you analyze your web page(s) pre-user journey. Analyze the Competitor Health Metric, Core Web Vitals, and Technology. Compare your web pages with your competitors to understand where you are leading or lagging. Real-time notification with Slack. Have Seamless Collaboration with Multiple Teams. Automate your Audits hourly, daily, weekly, and so on. It has a free trial with pay as you go plans.
358
+
355
359
  ## Lighthouse Integrations in non-Web Perf services
356
360
 
357
361
  * **[PageWatch](https://pagewatch.dev/)** — PageWatch is a tool to find problem pages on your website. It provides insights into spelling errors, layout issues, slow pages (powered by Lighthouse) and more. PageWatch is offered via free and paid plans.
@@ -24,7 +24,7 @@ function getAppsOrigin() {
24
24
  const isDev = new URLSearchParams(window.location.search).has('dev');
25
25
 
26
26
  if (isVercel) return `https://${window.location.host}/gh-pages`;
27
- if (isDev) return 'http://localhost:8000';
27
+ if (isDev) return 'http://localhost:7333';
28
28
  return 'https://googlechrome.github.io/lighthouse';
29
29
  }
30
30
 
package/types/config.d.ts CHANGED
@@ -28,7 +28,6 @@ declare module Config {
28
28
 
29
29
  // Fraggle Rock Only
30
30
  artifacts?: ArtifactJson[] | null;
31
- navigations?: NavigationJson[] | null;
32
31
 
33
32
  // Legacy Only
34
33
  passes?: PassJson[] | null;
@@ -99,6 +99,17 @@ export type ScreenEmulationSettings = {
99
99
  precomputedLanternData?: PrecomputedLanternData | null;
100
100
  /** The budget.json object for LightWallet. */
101
101
  budgets?: Array<Budget> | null;
102
+
103
+ /** The number of milliseconds to wait after FCP until the page should be considered loaded. */
104
+ pauseAfterFcpMs?: number;
105
+ /** The number of milliseconds to wait after the load event until the page should be considered loaded. */
106
+ pauseAfterLoadMs?: number;
107
+ /** The number of milliseconds to wait between high priority network requests or 3 simulataneous requests before the page should be considered loaded. */
108
+ networkQuietThresholdMs?: number;
109
+ /** The number of milliseconds to wait between long tasks until the page should be considered loaded. */
110
+ cpuQuietThresholdMs?: number;
111
+ /** The URL to use for the "blank" neutral page in between navigations. Defaults to `about:blank`. */
112
+ blankPage?: string;
102
113
  }
103
114
 
104
115
  export interface ConfigSettings extends Required<SharedFlagsSettings> {