GoogleChrome / GoogleChrome/lighthouse

Improve cleanup flow for programmatic usage

Open
#17,065 3 comments 0 reactions 0 assignees View on GitHub
Dominant language
JavaScript
Stars
30.8k
Forks
9.8k
Avg merge
1d 20h
Merged PRs (30d)
19

Description

## Motivation

When using the userflow api programatically we don't have a way to cleanup in case of cancelation or error.

Idealy the API exposes some destruction or dispose logic to avoid having to wait for something that already failed.

## Description

### Current state

When errors occure inside while attempting to execute flows you are not able to cancel ongoing timers and wait conditions.

For example here:

```typescript
import { writeFileSync } from 'fs';
import puppeteer from 'puppeteer';
import { startFlow } from 'lighthouse';

const browser = await puppeteer.launch();
const page = await browser.newPage();
const flow = await startFlow(page);

try {
await flow.startNavigation();
await page.goto('https://invalid-url.dev/');
await flow.endNavigation();

writeFileSync('report.html', await flow.generateReport());
} catch (error) {
console.error(error);
}

await browser.close();
```

You will get to errors:

```
Error: net::ERR_NAME_NOT_RESOLVED at https://invalid-url.dev/
at navigate (node_modules/.pnpm/puppeteer-core@24.43.1/node_modules/puppeteer-core/lib/esm/puppeteer/cdp/Frame.js:185:27)
at async Deferred.race (node_modules/.pnpm/puppeteer-core@24.43.1/node_modules/puppeteer-core/lib/esm/puppeteer/util/Deferred.js:33:20)
at async CdpFrame.goto (node_modules/.pnpm/puppeteer-core@24.43.1/node_modules/puppeteer-core/lib/esm/puppeteer/cdp/Frame.js:151:25)
at async CdpPage.goto (node_modules/.pnpm/puppeteer-core@24.43.1/node_modules/puppeteer-core/lib/esm/puppeteer/api/Page.js:576:20)
at async flow.mts:11:3

node_modules/.pnpm/lighthouse@13.3.0/node_modules/lighthouse/core/gather/driver/wait-for-condition.js:85
reject(new LighthouseError(LighthouseError.errors.NO_FCP));
^

LighthouseError: NO_FCP
at Timeout. (file:///Users/Christopher.Holder/Projects/app-speed/node_modules/.pnpm/lighthouse@13.3.0/node_modules/lighthouse/core/gather/driver/wait-for-condition.js:85:14)
at listOnTimeout (node:internal/timers:605:17)
at process.processTimers (node:internal/timers:541:7) {
code: 'NO_FCP',
friendlyMessage: 'The page did not paint any content. Please ensure you keep the browser window in the foreground during the load and try again. (NO_FCP)',
lhrRuntimeError: true
}
```

The second error will happen much later even after the browser has been terminated.

That is not really an issue when you are handling a single flow or executing one flow per process but if you want to run this progrematically then its not ideal.

### Potential improvement

We could expose a cancelation or dispose functionality to cleanup active parts of the flow.

```typescript

try {
await flow.startNavigation();
await page.goto('https://invalid-url.dev/');
await flow.endNavigation();

writeFileSync('report.html', await flow.generateReport());
} catch (error) {
await flow.dispose();
console.error(error);
}

```

I see the wait for condition that handles the timers and checks and i assume that would likely be the main contender of things that would benefit from cleanup.

I am willing to help with the implementation.

An example of why this is useful for lighthouse is https://appspeed.dev/user-flow which is something i am experimenting with. Its basically PageSpeed Insights but for UserFlow and not just the initial navigation.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.