browsertime 17.5.0-beta3 → 17.5.0
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/CHANGELOG.md +5 -2
- package/browserscripts/pageinfo/interactionToNextPaintInfo.js +12 -2
- package/browsertime/visualmetrics-portable.py +7 -6
- package/lib/firefox/getHAR.js +66 -0
- package/lib/firefox/webdriver/builder.js +25 -1
- package/lib/firefox/webdriver/firefox.js +19 -8
- package/lib/support/cli.js +6 -0
- package/package.json +2 -2
- package/vendor/har_export_trigger-0.6.1-an+fx.xpi +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
# Browsertime changelog (we do [semantic versioning](https://semver.org))
|
|
2
2
|
|
|
3
|
-
## 17.5.0 -
|
|
3
|
+
## 17.5.0 - 2022-04-04
|
|
4
4
|
|
|
5
5
|
### Added
|
|
6
|
-
* There's a new better way to get the HAR from [Firefox using WebDriver BiDi network events](https://github.com/firefox-devtools/bidi-har-export). Thank you [Julian Descottes](https://github.com/juliandescottes) and others at Mozilla that made this happen! With the new version we hope to see less overhead getting the HAR + it works on Firefox on Android [#1918](https://github.com/sitespeedio/browsertime/pull/1918).
|
|
6
|
+
* There's a new better way to get the HAR from [Firefox using WebDriver BiDi network events](https://github.com/firefox-devtools/bidi-har-export). Thank you [Julian Descottes](https://github.com/juliandescottes) and others at Mozilla that made this happen! With the new version we hope to see less overhead getting the HAR + it works on Firefox on Android [#1918](https://github.com/sitespeedio/browsertime/pull/1918). You can turn it on with `--firefox.bidihar`.
|
|
7
|
+
* Updated to Geckodriver 0.33 [#1928](https://github.com/sitespeedio/browsertime/pull/1928).
|
|
8
|
+
|
|
7
9
|
### Fixed
|
|
8
10
|
* Fixed the interaction to next paint error message that started to appear in latest Chrome [#1924](https://github.com/sitespeedio/browsertime/pull/1924).
|
|
11
|
+
* Safer check for getting last meaningful paint [#1927](https://github.com/sitespeedio/browsertime/pull/1927)
|
|
9
12
|
|
|
10
13
|
## 17.4.0 - 2022-03-29
|
|
11
14
|
### Added
|
|
@@ -86,7 +86,11 @@
|
|
|
86
86
|
) {
|
|
87
87
|
// If the interaction already exists, update it. Otherwise create one.
|
|
88
88
|
if (existingInteraction) {
|
|
89
|
-
existingInteraction.entries.push(
|
|
89
|
+
existingInteraction.entries.push(
|
|
90
|
+
{ id: entry.interactionId,
|
|
91
|
+
latency: entry.duration,
|
|
92
|
+
name: entry.name
|
|
93
|
+
});
|
|
90
94
|
existingInteraction.latency = Math.max(
|
|
91
95
|
existingInteraction.latency,
|
|
92
96
|
entry.duration
|
|
@@ -95,7 +99,13 @@
|
|
|
95
99
|
const interaction = {
|
|
96
100
|
id: entry.interactionId,
|
|
97
101
|
latency: entry.duration,
|
|
98
|
-
|
|
102
|
+
entries: [
|
|
103
|
+
{
|
|
104
|
+
id: entry.interactionId,
|
|
105
|
+
latency: entry.duration,
|
|
106
|
+
name: entry.name
|
|
107
|
+
}
|
|
108
|
+
]
|
|
99
109
|
};
|
|
100
110
|
longestInteractionMap[interaction.id] = interaction;
|
|
101
111
|
longestInteractionList.push(interaction);
|
|
@@ -1287,12 +1287,13 @@ def calculate_visual_metrics(
|
|
|
1287
1287
|
)
|
|
1288
1288
|
# hero_timings.append({'name': 'FirstPaintedHero',
|
|
1289
1289
|
# 'value': hero_timings_sorted[0]['value']})
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1290
|
+
if (len(hero_timings_sorted) > 0):
|
|
1291
|
+
hero_timings.append(
|
|
1292
|
+
{
|
|
1293
|
+
"name": "LastMeaningfulPaint",
|
|
1294
|
+
"value": hero_timings_sorted[-1]["value"],
|
|
1295
|
+
}
|
|
1296
|
+
)
|
|
1296
1297
|
hero_data["timings"] = hero_timings
|
|
1297
1298
|
metrics += hero_timings
|
|
1298
1299
|
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import intel from 'intel';
|
|
2
|
+
const log = intel.getLogger('browsertime.firefox');
|
|
3
|
+
|
|
4
|
+
// Get the HAR from Firefox
|
|
5
|
+
// Using https://github.com/firefox-devtools/har-export-trigger
|
|
6
|
+
export async function getHAR(runner, includeResponseBodies) {
|
|
7
|
+
const script = `
|
|
8
|
+
const callback = arguments[arguments.length - 1];
|
|
9
|
+
async function triggerExport() {
|
|
10
|
+
try {
|
|
11
|
+
const result = await HAR.triggerExport();
|
|
12
|
+
if (result.pages.length > 0) {
|
|
13
|
+
result.pages[0].title = document.URL;
|
|
14
|
+
return callback({'har': {log: result}});
|
|
15
|
+
} else {
|
|
16
|
+
return callback({'error': 'The HAR export trigger returned an empty HAR' + JSON.stringify(result)});
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
catch(e) {
|
|
20
|
+
// Sometimes the HAR trigger is really slow so then HAR is not defined.
|
|
21
|
+
// we catch that with one extra delay
|
|
22
|
+
const delay = ms => new Promise(res => setTimeout(res, ms));
|
|
23
|
+
await delay(10000);
|
|
24
|
+
try {
|
|
25
|
+
const result = await HAR.triggerExport();
|
|
26
|
+
result.pages[0].title = document.URL;
|
|
27
|
+
return callback({'har': {log: result}});
|
|
28
|
+
} catch(e) {
|
|
29
|
+
return callback({'error': e.toString()});
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
return triggerExport();
|
|
34
|
+
`;
|
|
35
|
+
|
|
36
|
+
log.info('Waiting on har-export-trigger to collect the HAR');
|
|
37
|
+
try {
|
|
38
|
+
const harResult = await runner.runAsyncScript(script, 'GET_HAR_SCRIPT');
|
|
39
|
+
if (harResult.har) {
|
|
40
|
+
// The HAR from Firefox always includes content and that can make the HAR file
|
|
41
|
+
// really big, so we have an option to remove it.
|
|
42
|
+
if (
|
|
43
|
+
includeResponseBodies === 'none' ||
|
|
44
|
+
includeResponseBodies === 'html'
|
|
45
|
+
) {
|
|
46
|
+
for (let entry of harResult.har.log.entries) {
|
|
47
|
+
if (includeResponseBodies === 'none') {
|
|
48
|
+
delete entry.response.content.text;
|
|
49
|
+
} else if (
|
|
50
|
+
entry.response.content.mimeType &&
|
|
51
|
+
!entry.response.content.mimeType.includes('text/html')
|
|
52
|
+
) {
|
|
53
|
+
delete entry.response.content.text;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return harResult.har;
|
|
58
|
+
} else {
|
|
59
|
+
log.error(
|
|
60
|
+
'Got an error from HAR Export Trigger ' + JSON.stringify(harResult)
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
} catch (error) {
|
|
64
|
+
log.error('Could not get the HAR from Firefox', error);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
@@ -176,7 +176,31 @@ export async function configureBuilder(builder, baseDir, options) {
|
|
|
176
176
|
ffOptions.addArguments('-no-remote');
|
|
177
177
|
|
|
178
178
|
// Enable bidi for HAR support
|
|
179
|
-
|
|
179
|
+
if (firefoxConfig.bidihar) {
|
|
180
|
+
ffOptions.enableBidi();
|
|
181
|
+
} else {
|
|
182
|
+
if (!options.skipHar) {
|
|
183
|
+
if (isAndroidConfigured(options)) {
|
|
184
|
+
log.info('Skip install HAR trigger on Android');
|
|
185
|
+
} else {
|
|
186
|
+
// Hack for opening the toolbar
|
|
187
|
+
// In Firefox 61 we need to have devtools open but do not need to choose netmonitor
|
|
188
|
+
// ffOptions.setPreference('devtools.toolbox.selectedTool', 'netmonitor');
|
|
189
|
+
if (!options.debug) {
|
|
190
|
+
ffOptions.setPreference('devtools.toolbox.footer.height', 0);
|
|
191
|
+
ffOptions.addArguments('-devtools');
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
ffOptions.addExtensions(
|
|
195
|
+
resolve(
|
|
196
|
+
moduleRootPath,
|
|
197
|
+
'vendor',
|
|
198
|
+
'har_export_trigger-0.6.1-an+fx.xpi'
|
|
199
|
+
)
|
|
200
|
+
);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
180
204
|
|
|
181
205
|
if (firefoxConfig.args) {
|
|
182
206
|
ffOptions.addArguments(firefoxConfig.args);
|
|
@@ -12,6 +12,7 @@ import { findFiles } from '../../support/fileUtil.js';
|
|
|
12
12
|
import { GeckoProfiler } from '../geckoProfiler.js';
|
|
13
13
|
import { MemoryReport } from '../memoryReport.js';
|
|
14
14
|
import { PerfStats } from '../perfStats.js';
|
|
15
|
+
import { getHAR } from '../getHAR.js';
|
|
15
16
|
|
|
16
17
|
const log = intel.getLogger('browsertime.firefox');
|
|
17
18
|
const rename = promisify(_rename);
|
|
@@ -50,11 +51,13 @@ export class Firefox {
|
|
|
50
51
|
* configure what you need.
|
|
51
52
|
*/
|
|
52
53
|
async afterBrowserStart(runner) {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
54
|
+
if (this.firefoxConfig.bidihar) {
|
|
55
|
+
const windowId = await runner.getDriver().getWindowHandle();
|
|
56
|
+
this.har = new adapters.SeleniumBiDiHarRecorder({
|
|
57
|
+
browsingContextIds: [windowId],
|
|
58
|
+
driver: runner.getDriver()
|
|
59
|
+
});
|
|
60
|
+
}
|
|
58
61
|
}
|
|
59
62
|
|
|
60
63
|
/**
|
|
@@ -88,7 +91,7 @@ export class Firefox {
|
|
|
88
91
|
});
|
|
89
92
|
`);
|
|
90
93
|
|
|
91
|
-
if (!this.skipHar) {
|
|
94
|
+
if (!this.skipHar && this.firefoxConfig.bidihar) {
|
|
92
95
|
await this.har.startRecording();
|
|
93
96
|
}
|
|
94
97
|
|
|
@@ -177,11 +180,19 @@ export class Firefox {
|
|
|
177
180
|
}
|
|
178
181
|
result.cpu = powerusage;
|
|
179
182
|
|
|
180
|
-
if (
|
|
183
|
+
if (
|
|
184
|
+
this.skipHar ||
|
|
185
|
+
(isAndroidConfigured(this.options) && !this.firefoxConfig.bidihar)
|
|
186
|
+
) {
|
|
187
|
+
if (result.alias && !this.aliasAndUrl[result.alias]) {
|
|
188
|
+
this.aliasAndUrl[result.alias] = result.url;
|
|
189
|
+
}
|
|
181
190
|
return result;
|
|
182
191
|
} else {
|
|
183
192
|
// const harExport = await this.har.stopRecording();
|
|
184
|
-
const har =
|
|
193
|
+
const har = this.firefoxConfig.bidihar
|
|
194
|
+
? await this.har.stopRecording()
|
|
195
|
+
: await getHAR(runner, this.includeResponseBodies);
|
|
185
196
|
if (har.log.pages.length > 0) {
|
|
186
197
|
// Hack to add the URL from a SPA
|
|
187
198
|
if (result.alias && !this.aliasAndUrl[result.alias]) {
|
package/lib/support/cli.js
CHANGED
|
@@ -438,6 +438,12 @@ export function parseCommandLine() {
|
|
|
438
438
|
type: 'boolean',
|
|
439
439
|
group: 'firefox'
|
|
440
440
|
})
|
|
441
|
+
.option('firefox.bidihar', {
|
|
442
|
+
describe: 'Use the new bidi HAR generator',
|
|
443
|
+
default: false,
|
|
444
|
+
type: 'boolean',
|
|
445
|
+
group: 'firefox'
|
|
446
|
+
})
|
|
441
447
|
.option('firefox.windowRecorder', {
|
|
442
448
|
describe:
|
|
443
449
|
'Use the internal compositor-based Firefox window recorder to emit PNG files for each ' +
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "browsertime",
|
|
3
3
|
"description": "Get performance metrics from your web page using Browsertime.",
|
|
4
|
-
"version": "17.5.0
|
|
4
|
+
"version": "17.5.0",
|
|
5
5
|
"bin": "./bin/browsertime.js",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"dependencies": {
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"@devicefarmer/adbkit": "2.11.3",
|
|
10
10
|
"@sitespeed.io/chromedriver": "111.0.5563-64",
|
|
11
11
|
"@sitespeed.io/edgedriver": "111.0.1661-41",
|
|
12
|
-
"@sitespeed.io/geckodriver": "0.
|
|
12
|
+
"@sitespeed.io/geckodriver": "0.33.0",
|
|
13
13
|
"@sitespeed.io/throttle": "5.0.0",
|
|
14
14
|
"@sitespeed.io/tracium": "0.3.3",
|
|
15
15
|
"ff-test-bidi-har-export": "0.0.6",
|
|
Binary file
|