@browserless/cli 13.6.13 → 13.7.1
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/README.md +1 -1
- package/package.json +4 -4
- package/src/commands/page-weight.js +31 -13
package/README.md
CHANGED
|
@@ -47,7 +47,7 @@ The `@browserless/cli` package allows you to:
|
|
|
47
47
|
| `html <url>` | Serialize the page content to HTML |
|
|
48
48
|
| `text <url>` | Extract plain text content from the page |
|
|
49
49
|
| `lighthouse <url>` | Run a Google Lighthouse audit and output JSON report |
|
|
50
|
-
| `page-weight <url>` | Analyze network requests
|
|
50
|
+
| `page-weight <url>` | Analyze network requests, resource sizes, and basic load timings |
|
|
51
51
|
| `ping <url>` | Get response info: status code, redirects, headers |
|
|
52
52
|
| `status <url>` | Get the HTTP status code |
|
|
53
53
|
| `goto <url>` | Navigate to a URL and return page/response info |
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@browserless/cli",
|
|
3
3
|
"description": "Command-line interface for headless browser automation. Take screenshots, generate PDFs, and extract content from websites.",
|
|
4
4
|
"homepage": "https://browserless.js.org",
|
|
5
|
-
"version": "13.
|
|
5
|
+
"version": "13.7.1",
|
|
6
6
|
"bin": {
|
|
7
7
|
"browserless": "src/index.js"
|
|
8
8
|
},
|
|
@@ -34,9 +34,9 @@
|
|
|
34
34
|
"web-scraping"
|
|
35
35
|
],
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@browserless/capture": "13.
|
|
37
|
+
"@browserless/capture": "13.7.1",
|
|
38
38
|
"beauty-error": "~1.2.22",
|
|
39
|
-
"browserless": "13.
|
|
39
|
+
"browserless": "13.7.1",
|
|
40
40
|
"dark-mode": "~3.0.0",
|
|
41
41
|
"dset": "~3.1.4",
|
|
42
42
|
"mri": "~1.2.0",
|
|
@@ -59,5 +59,5 @@
|
|
|
59
59
|
"test": "exit 0"
|
|
60
60
|
},
|
|
61
61
|
"license": "MIT",
|
|
62
|
-
"gitHead": "
|
|
62
|
+
"gitHead": "366c1854294079765b40ebc755981142ab78f1ac"
|
|
63
63
|
}
|
|
@@ -2,17 +2,30 @@
|
|
|
2
2
|
|
|
3
3
|
const prettyBytes = require('pretty-bytes')
|
|
4
4
|
|
|
5
|
+
// Navigation Timing uses 0 for milestones that haven't been recorded.
|
|
6
|
+
const timing = (ms, label) => (ms > 0 ? `${Math.round(ms)} ms ${label}` : null)
|
|
7
|
+
|
|
5
8
|
module.exports = async ({ url, browserless, opts }) => {
|
|
6
|
-
const
|
|
7
|
-
page.evaluate(() =>
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
const getPageWeight = browserless.evaluate(async page =>
|
|
10
|
+
page.evaluate(() => {
|
|
11
|
+
const nav = performance.getEntriesByType('navigation')[0]
|
|
12
|
+
const paint = performance.getEntriesByType('paint')
|
|
13
|
+
const fcp = paint.find(e => e.name === 'first-contentful-paint')
|
|
14
|
+
|
|
15
|
+
return {
|
|
16
|
+
resources: performance.getEntriesByType('resource').map(resource => ({
|
|
17
|
+
transferredSize: resource.transferSize,
|
|
18
|
+
decodedBodySize: resource.decodedBodySize
|
|
19
|
+
})),
|
|
20
|
+
ttfb: nav?.responseStart,
|
|
21
|
+
fcp: fcp?.startTime,
|
|
22
|
+
domContentLoaded: nav?.domContentLoadedEventEnd,
|
|
23
|
+
loadEventEnd: nav?.loadEventEnd
|
|
24
|
+
}
|
|
25
|
+
})
|
|
13
26
|
)
|
|
14
27
|
|
|
15
|
-
const resources = await
|
|
28
|
+
const { resources, ttfb, fcp, domContentLoaded, loadEventEnd } = await getPageWeight(url, opts)
|
|
16
29
|
|
|
17
30
|
const [transferSize, resourcesSize] = resources
|
|
18
31
|
.reduce(
|
|
@@ -25,10 +38,15 @@ module.exports = async ({ url, browserless, opts }) => {
|
|
|
25
38
|
)
|
|
26
39
|
.map(prettyBytes)
|
|
27
40
|
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
41
|
+
const lines = [
|
|
42
|
+
`${resources.length} network requests`,
|
|
43
|
+
`${transferSize} transferred bytes`,
|
|
44
|
+
`${resourcesSize} resources bytes`,
|
|
45
|
+
timing(ttfb, 'TTFB'),
|
|
46
|
+
timing(fcp, 'FCP'),
|
|
47
|
+
timing(domContentLoaded, 'DOMContentLoaded'),
|
|
48
|
+
timing(loadEventEnd, 'load')
|
|
49
|
+
].filter(Boolean)
|
|
32
50
|
|
|
33
|
-
return [
|
|
51
|
+
return ['\n' + lines.map(line => ` ⬩ ${line}`).join('\n')]
|
|
34
52
|
}
|