GoogleChrome / GoogleChrome/lighthouse
Improve cleanup flow for programmatic usage
- 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
Assessment
This issue has not been assessed yet.