GoogleChrome / GoogleChrome/lighthouse

Scrolling in a user-flow timespan not working correctly on a server

Open
#14,540 5 comments 0 reactions 1 assignee Claimed by @paulirish View on GitHub
needs-more-info P2
Dominant language
JavaScript
Stars
30.8k
Forks
9.8k
Avg merge
1d 20h
Merged PRs (30d)
19

Description

**Summary**
Running Lighthouse User Flow on a server fails to capture the scrolling timespans correctly.

I am trying to build something similar to [PageSpeed Insights](https://pagespeed.web.dev) but that can capture user flows. The idea is that you will be able to run Replay Records or custom user-flows, but i am starting with a simple predefined user-flow as a prof of concept.

The project is built on top of [@push-based/user-flow](https://github.com/push-based/user-flow/) and runs on an EC2 m5.large instance to reduce variability in the results.

The issue I am having is that when running the audit on the server it is not able to capture scrolling correctly.
[Local Audit Result](https://deepblue-userflow-records.s3.eu-central-1.amazonaws.com/deep-blue-performance-test.uf.html)
[Remote Audit Result](https://deepblue-userflow-records.s3.eu-central-1.amazonaws.com/2022-10-18T09_59deep-blue.io.uf.html)

[Related issue #14463](https://github.com/GoogleChrome/lighthouse/issues/14463)

To achieve the scrolling I am using [Protocol.Input.SynthesizeScrollGestureRequest](https://chromedevtools.github.io/devtools-protocol/tot/Input/#method-synthesizeScrollGesture)

```ts
export class ScrollAction {
private session?: CDPSession;
constructor(private readonly page: Page) {}

async swipeToPageBottom(): Promise {
await this.page.waitForSelector('body');
await this._synthesizeTouchScroll('down');
}

async swipeToPageTop(): Promise {
await this.page.waitForSelector('body');
await this._synthesizeTouchScroll('up');
}

private async _synthesizeTouchScroll(direction: 'down' | 'up'): Promise {
const scrollParams = await this._getScrollParams(direction);
this.session = await this.page.target().createCDPSession();
// https://chromedevtools.github.io/devtools-protocol/tot/Input/#method-synthesizeScrollGesture
await this.session.send('Input.synthesizeScrollGesture', scrollParams);
}

private async _getScrollParams(direction: 'down' | 'up'): Promise {
const innerHeight = await this._getInnerContentHeight();
const x = 200;
const y = direction === 'up' ? 200 : 600;
const scrollDistance = 1500;
const speed = 800;
const repeatDelayMs = 250;
const yDistance = direction === 'up' ? scrollDistance : scrollDistance * (-1);
const repeatCount = Math.ceil(innerHeight / scrollDistance) - 1;
const gestureSourceType = 'touch';
return {x, y, yDistance, speed, repeatCount, repeatDelayMs, gestureSourceType};
}

private async _getInnerContentHeight(): Promise {
const innerContentHandle = await this.page.$('body');
const innerContentBox = await innerContentHandle!.boundingBox();
return innerContentBox!.height;
}
}
```

The rest of the code is publicly avalible: [ufo repo](https://github.com/ChristopherPHolder/ufo).
And the url to be able to run it on the server is [Userflow Runner](https://deep-blue.io/userflows/)

I also read that @connorjclark was looking into "some types of INP that could be automatically tested". Is there a discution or an issue where i can read up on that to see if i can include any of them in my Web User Flow Runner?

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.