pagespeed 1.2.2__tar.gz
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.
- pagespeed-1.2.2/.gitignore +186 -0
- pagespeed-1.2.2/LICENSE +21 -0
- pagespeed-1.2.2/PKG-INFO +399 -0
- pagespeed-1.2.2/README.md +380 -0
- pagespeed-1.2.2/pagespeed_insights_tool.py +1856 -0
- pagespeed-1.2.2/pyproject.toml +33 -0
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
# Created by https://www.toptal.com/developers/gitignore/api/node,macos
|
|
2
|
+
# Edit at https://www.toptal.com/developers/gitignore?templates=node,macos
|
|
3
|
+
|
|
4
|
+
### macOS ###
|
|
5
|
+
# General
|
|
6
|
+
.DS_Store
|
|
7
|
+
.AppleDouble
|
|
8
|
+
.LSOverride
|
|
9
|
+
|
|
10
|
+
# Icon must end with two \r
|
|
11
|
+
Icon
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
# Thumbnails
|
|
15
|
+
._*
|
|
16
|
+
|
|
17
|
+
# Files that might appear in the root of a volume
|
|
18
|
+
.DocumentRevisions-V100
|
|
19
|
+
.fseventsd
|
|
20
|
+
.Spotlight-V100
|
|
21
|
+
.TemporaryItems
|
|
22
|
+
.Trashes
|
|
23
|
+
.VolumeIcon.icns
|
|
24
|
+
.com.apple.timemachine.donotpresent
|
|
25
|
+
|
|
26
|
+
# Directories potentially created on remote AFP share
|
|
27
|
+
.AppleDB
|
|
28
|
+
.AppleDesktop
|
|
29
|
+
Network Trash Folder
|
|
30
|
+
Temporary Items
|
|
31
|
+
.apdisk
|
|
32
|
+
|
|
33
|
+
### macOS Patch ###
|
|
34
|
+
# iCloud generated files
|
|
35
|
+
*.icloud
|
|
36
|
+
|
|
37
|
+
### Node ###
|
|
38
|
+
# Logs
|
|
39
|
+
logs
|
|
40
|
+
*.log
|
|
41
|
+
npm-debug.log*
|
|
42
|
+
yarn-debug.log*
|
|
43
|
+
yarn-error.log*
|
|
44
|
+
lerna-debug.log*
|
|
45
|
+
.pnpm-debug.log*
|
|
46
|
+
|
|
47
|
+
# Diagnostic reports (https://nodejs.org/api/report.html)
|
|
48
|
+
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
|
49
|
+
|
|
50
|
+
# Runtime data
|
|
51
|
+
pids
|
|
52
|
+
*.pid
|
|
53
|
+
*.seed
|
|
54
|
+
*.pid.lock
|
|
55
|
+
|
|
56
|
+
# Directory for instrumented libs generated by jscoverage/JSCover
|
|
57
|
+
lib-cov
|
|
58
|
+
|
|
59
|
+
# Coverage directory used by tools like istanbul
|
|
60
|
+
coverage
|
|
61
|
+
*.lcov
|
|
62
|
+
|
|
63
|
+
# nyc test coverage
|
|
64
|
+
.nyc_output
|
|
65
|
+
|
|
66
|
+
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
|
67
|
+
.grunt
|
|
68
|
+
|
|
69
|
+
# Bower dependency directory (https://bower.io/)
|
|
70
|
+
bower_components
|
|
71
|
+
|
|
72
|
+
# node-waf configuration
|
|
73
|
+
.lock-wscript
|
|
74
|
+
|
|
75
|
+
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
|
76
|
+
build/Release
|
|
77
|
+
|
|
78
|
+
# Dependency directories
|
|
79
|
+
node_modules/
|
|
80
|
+
jspm_packages/
|
|
81
|
+
|
|
82
|
+
# Snowpack dependency directory (https://snowpack.dev/)
|
|
83
|
+
web_modules/
|
|
84
|
+
|
|
85
|
+
# TypeScript cache
|
|
86
|
+
*.tsbuildinfo
|
|
87
|
+
|
|
88
|
+
# Optional npm cache directory
|
|
89
|
+
.npm
|
|
90
|
+
|
|
91
|
+
# Optional eslint cache
|
|
92
|
+
.eslintcache
|
|
93
|
+
|
|
94
|
+
# Optional stylelint cache
|
|
95
|
+
.stylelintcache
|
|
96
|
+
|
|
97
|
+
# Microbundle cache
|
|
98
|
+
.rpt2_cache/
|
|
99
|
+
.rts2_cache_cjs/
|
|
100
|
+
.rts2_cache_es/
|
|
101
|
+
.rts2_cache_umd/
|
|
102
|
+
|
|
103
|
+
# Optional REPL history
|
|
104
|
+
.node_repl_history
|
|
105
|
+
|
|
106
|
+
# Output of 'npm pack'
|
|
107
|
+
*.tgz
|
|
108
|
+
|
|
109
|
+
# Yarn Integrity file
|
|
110
|
+
.yarn-integrity
|
|
111
|
+
|
|
112
|
+
# dotenv environment variable files
|
|
113
|
+
.env
|
|
114
|
+
.env.development.local
|
|
115
|
+
.env.test.local
|
|
116
|
+
.env.production.local
|
|
117
|
+
.env.local
|
|
118
|
+
|
|
119
|
+
# parcel-bundler cache (https://parceljs.org/)
|
|
120
|
+
.cache
|
|
121
|
+
.parcel-cache
|
|
122
|
+
|
|
123
|
+
# Next.js build output
|
|
124
|
+
.next
|
|
125
|
+
out
|
|
126
|
+
|
|
127
|
+
# Nuxt.js build / generate output
|
|
128
|
+
.nuxt
|
|
129
|
+
dist
|
|
130
|
+
|
|
131
|
+
# Gatsby files
|
|
132
|
+
.cache/
|
|
133
|
+
# Comment in the public line in if your project uses Gatsby and not Next.js
|
|
134
|
+
# https://nextjs.org/blog/next-9-1#public-directory-support
|
|
135
|
+
# public
|
|
136
|
+
|
|
137
|
+
# vuepress build output
|
|
138
|
+
.vuepress/dist
|
|
139
|
+
|
|
140
|
+
# vuepress v2.x temp and cache directory
|
|
141
|
+
.temp
|
|
142
|
+
|
|
143
|
+
# Docusaurus cache and generated files
|
|
144
|
+
.docusaurus
|
|
145
|
+
|
|
146
|
+
# Serverless directories
|
|
147
|
+
.serverless/
|
|
148
|
+
|
|
149
|
+
# FuseBox cache
|
|
150
|
+
.fusebox/
|
|
151
|
+
|
|
152
|
+
# DynamoDB Local files
|
|
153
|
+
.dynamodb/
|
|
154
|
+
|
|
155
|
+
# TernJS port file
|
|
156
|
+
.tern-port
|
|
157
|
+
|
|
158
|
+
# Stores VSCode versions used for testing VSCode extensions
|
|
159
|
+
.vscode-test
|
|
160
|
+
|
|
161
|
+
# yarn v2
|
|
162
|
+
.yarn/cache
|
|
163
|
+
.yarn/unplugged
|
|
164
|
+
.yarn/build-state.yml
|
|
165
|
+
.yarn/install-state.gz
|
|
166
|
+
.pnp.*
|
|
167
|
+
|
|
168
|
+
### Node Patch ###
|
|
169
|
+
# Serverless Webpack directories
|
|
170
|
+
.webpack/
|
|
171
|
+
|
|
172
|
+
# Optional stylelint cache
|
|
173
|
+
|
|
174
|
+
# SvelteKit build / generate output
|
|
175
|
+
.svelte-kit
|
|
176
|
+
|
|
177
|
+
# End of https://www.toptal.com/developers/gitignore/api/node,macos
|
|
178
|
+
__pycache__/
|
|
179
|
+
*.pyc
|
|
180
|
+
*.pyo
|
|
181
|
+
*.pyd
|
|
182
|
+
.Python
|
|
183
|
+
dist/
|
|
184
|
+
build/
|
|
185
|
+
*.egg-info/
|
|
186
|
+
.claude/settings.local.json
|
pagespeed-1.2.2/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Otter
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
pagespeed-1.2.2/PKG-INFO
ADDED
|
@@ -0,0 +1,399 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pagespeed
|
|
3
|
+
Version: 1.2.2
|
|
4
|
+
Summary: CLI tool for batch Google PageSpeed Insights analysis with CSV/JSON/HTML reports
|
|
5
|
+
Project-URL: Homepage, https://github.com/volkanunsal/pagespeed
|
|
6
|
+
Project-URL: Repository, https://github.com/volkanunsal/pagespeed
|
|
7
|
+
Project-URL: Issues, https://github.com/volkanunsal/pagespeed/issues
|
|
8
|
+
License-Expression: MIT
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Keywords: core-web-vitals,lighthouse,pagespeed,performance,web-vitals
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Environment :: Console
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
14
|
+
Classifier: Topic :: Internet :: WWW/HTTP :: Site Management
|
|
15
|
+
Requires-Python: >=3.13
|
|
16
|
+
Requires-Dist: pandas
|
|
17
|
+
Requires-Dist: requests
|
|
18
|
+
Description-Content-Type: text/markdown
|
|
19
|
+
|
|
20
|
+
# PageSpeed Insights Batch Analysis Tool
|
|
21
|
+
|
|
22
|
+
A command-line tool that automates Google PageSpeed Insights analysis across multiple URLs, extracting performance metrics (lab + field data) into structured CSV, JSON, and HTML reports.
|
|
23
|
+
|
|
24
|
+
## Installation
|
|
25
|
+
|
|
26
|
+
### Run instantly with `uvx` (recommended, no install needed)
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
uvx pagespeed quick-check https://example.com
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### Install with `pip` or `pipx`
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
pip install pagespeed
|
|
36
|
+
pagespeed quick-check https://example.com
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### Run from URL (just needs `uv`)
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
uv run https://raw.githubusercontent.com/volkanunsal/pagespeed/main/pagespeed_insights_tool.py quick-check https://example.com
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Development
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
git clone https://github.com/volkanunsal/pagespeed.git
|
|
49
|
+
cd pagespeed
|
|
50
|
+
uv run pagespeed_insights_tool.py quick-check https://example.com
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Prerequisites
|
|
54
|
+
|
|
55
|
+
- **Python 3.13+**
|
|
56
|
+
- **Google API key** (optional) — without one, you're limited to ~25 queries/day; with one, ~25,000/day
|
|
57
|
+
|
|
58
|
+
## Getting an API Key
|
|
59
|
+
|
|
60
|
+
1. Go to the [Google Cloud Console](https://console.cloud.google.com/)
|
|
61
|
+
2. Create a new project (or select an existing one)
|
|
62
|
+
3. Navigate to **APIs & Services > Library**
|
|
63
|
+
4. Search for **PageSpeed Insights API** and enable it
|
|
64
|
+
5. Go to **APIs & Services > Credentials**
|
|
65
|
+
6. Click **Create Credentials > API Key**
|
|
66
|
+
7. Copy the key and set it:
|
|
67
|
+
```bash
|
|
68
|
+
export PAGESPEED_API_KEY=your_key_here
|
|
69
|
+
```
|
|
70
|
+
Or add it to your `pagespeed.toml` config file (see [Configuration](#configuration)).
|
|
71
|
+
|
|
72
|
+
## Usage
|
|
73
|
+
|
|
74
|
+
### `quick-check` — Fast single-URL spot check
|
|
75
|
+
|
|
76
|
+
Prints a formatted report to the terminal. No files written.
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
# Mobile only (default)
|
|
80
|
+
pagespeed quick-check https://www.google.com
|
|
81
|
+
|
|
82
|
+
# Both mobile and desktop
|
|
83
|
+
pagespeed quick-check https://www.google.com --strategy both
|
|
84
|
+
|
|
85
|
+
# With specific categories
|
|
86
|
+
pagespeed quick-check https://www.google.com --categories performance accessibility
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Sample output:
|
|
90
|
+
|
|
91
|
+
```
|
|
92
|
+
============================================================
|
|
93
|
+
URL: https://www.google.com
|
|
94
|
+
Strategy: mobile
|
|
95
|
+
============================================================
|
|
96
|
+
Performance Score: 92/100 (GOOD)
|
|
97
|
+
|
|
98
|
+
--- Lab Data ---
|
|
99
|
+
First Contentful Paint............. 1200ms
|
|
100
|
+
Largest Contentful Paint........... 1800ms
|
|
101
|
+
Cumulative Layout Shift............ 0.0100
|
|
102
|
+
Speed Index........................ 1500ms
|
|
103
|
+
Total Blocking Time................ 150ms
|
|
104
|
+
Time to Interactive................ 2100ms
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### `audit` — Full batch analysis
|
|
108
|
+
|
|
109
|
+
Analyzes multiple URLs and writes CSV/JSON reports.
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
# From a file of URLs
|
|
113
|
+
pagespeed audit -f urls.txt
|
|
114
|
+
|
|
115
|
+
# Multiple strategies and output formats
|
|
116
|
+
pagespeed audit -f urls.txt --strategy both --output-format both
|
|
117
|
+
|
|
118
|
+
# Inline URLs with custom output path
|
|
119
|
+
pagespeed audit https://a.com https://b.com -o report
|
|
120
|
+
|
|
121
|
+
# With a named profile
|
|
122
|
+
pagespeed audit -f urls.txt --profile full
|
|
123
|
+
|
|
124
|
+
# Piped input
|
|
125
|
+
cat urls.txt | pagespeed audit
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
The URL file is one URL per line. Lines starting with `#` are comments:
|
|
129
|
+
|
|
130
|
+
```
|
|
131
|
+
# Main pages
|
|
132
|
+
https://example.com
|
|
133
|
+
https://example.com/about
|
|
134
|
+
https://example.com/contact
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### `compare` — Compare two reports
|
|
138
|
+
|
|
139
|
+
Loads two previous report files and shows per-URL score changes.
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
# Compare before and after
|
|
143
|
+
pagespeed compare before.csv after.csv
|
|
144
|
+
|
|
145
|
+
# Custom threshold (flag changes >= 10%)
|
|
146
|
+
pagespeed compare --threshold 10 old.json new.json
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Output flags regressions with `!!` and improvements with `++`.
|
|
150
|
+
|
|
151
|
+
### `report` — Generate HTML dashboard
|
|
152
|
+
|
|
153
|
+
Creates a self-contained HTML report from a results file.
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
# Generate HTML from CSV results
|
|
157
|
+
pagespeed report results.csv
|
|
158
|
+
|
|
159
|
+
# Custom output path
|
|
160
|
+
pagespeed report results.json -o dashboard.html
|
|
161
|
+
|
|
162
|
+
# Auto-open in browser
|
|
163
|
+
pagespeed report results.csv --open
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
The HTML report includes:
|
|
167
|
+
- Summary cards (total URLs, average/best/worst scores)
|
|
168
|
+
- Color-coded score table (green/orange/red)
|
|
169
|
+
- Core Web Vitals pass/fail indicators
|
|
170
|
+
- Bar charts comparing scores across URLs
|
|
171
|
+
- Field data table (when available)
|
|
172
|
+
- Sortable columns (click headers)
|
|
173
|
+
|
|
174
|
+
### `run` — Low-level direct access
|
|
175
|
+
|
|
176
|
+
Full control with every CLI flag. Same internals as `audit`.
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
pagespeed run https://example.com --strategy desktop --categories performance accessibility --delay 2.0
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
## Configuration
|
|
183
|
+
|
|
184
|
+
### Config file: `pagespeed.toml`
|
|
185
|
+
|
|
186
|
+
An optional TOML file for persistent settings and named profiles. The tool searches for it in:
|
|
187
|
+
1. Current working directory (`./pagespeed.toml`)
|
|
188
|
+
2. User config directory (`~/.config/pagespeed/config.toml`)
|
|
189
|
+
|
|
190
|
+
You can also pass an explicit path with `--config path/to/config.toml`.
|
|
191
|
+
|
|
192
|
+
```toml
|
|
193
|
+
[settings]
|
|
194
|
+
api_key = "YOUR_API_KEY" # or use PAGESPEED_API_KEY env var
|
|
195
|
+
urls_file = "urls.txt" # default URL file for -f
|
|
196
|
+
delay = 1.5 # seconds between API requests
|
|
197
|
+
strategy = "mobile" # mobile, desktop, or both
|
|
198
|
+
output_format = "csv" # csv, json, or both
|
|
199
|
+
output_dir = "./reports" # directory for output files
|
|
200
|
+
workers = 4 # concurrent workers (1 = sequential)
|
|
201
|
+
categories = ["performance"] # Lighthouse categories
|
|
202
|
+
verbose = false
|
|
203
|
+
|
|
204
|
+
[profiles.quick]
|
|
205
|
+
strategy = "mobile"
|
|
206
|
+
output_format = "csv"
|
|
207
|
+
categories = ["performance"]
|
|
208
|
+
|
|
209
|
+
[profiles.full]
|
|
210
|
+
strategy = "both"
|
|
211
|
+
output_format = "both"
|
|
212
|
+
categories = ["performance", "accessibility", "best-practices", "seo"]
|
|
213
|
+
|
|
214
|
+
[profiles.core-vitals]
|
|
215
|
+
strategy = "both"
|
|
216
|
+
output_format = "csv"
|
|
217
|
+
categories = ["performance"]
|
|
218
|
+
|
|
219
|
+
[profiles.client-report]
|
|
220
|
+
urls_file = "client_urls.txt"
|
|
221
|
+
strategy = "both"
|
|
222
|
+
output_format = "both"
|
|
223
|
+
output_dir = "./client-reports"
|
|
224
|
+
categories = ["performance", "accessibility", "seo"]
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
### Config resolution order
|
|
228
|
+
|
|
229
|
+
Settings are merged with the following priority (highest wins):
|
|
230
|
+
|
|
231
|
+
1. **CLI flags** — explicit command-line arguments
|
|
232
|
+
2. **Profile values** — via `--profile name`
|
|
233
|
+
3. **`[settings]`** — defaults from config file
|
|
234
|
+
4. **Built-in defaults** — hardcoded in the script
|
|
235
|
+
|
|
236
|
+
### Global flags
|
|
237
|
+
|
|
238
|
+
| Flag | Short | Default | Description |
|
|
239
|
+
|------|-------|---------|-------------|
|
|
240
|
+
| `--api-key` | — | config/env | Google API key |
|
|
241
|
+
| `--config` | `-c` | auto-discovered | Path to config TOML |
|
|
242
|
+
| `--profile` | `-p` | None | Named profile from config |
|
|
243
|
+
| `--verbose` | `-v` | False | Verbose output to stderr |
|
|
244
|
+
| `--version` | — | — | Print version and exit |
|
|
245
|
+
|
|
246
|
+
### `audit` / `run` flags
|
|
247
|
+
|
|
248
|
+
| Flag | Short | Default | Description |
|
|
249
|
+
|------|-------|---------|-------------|
|
|
250
|
+
| `urls` | — | `[]` | Positional URLs |
|
|
251
|
+
| `--file` | `-f` | None | File with one URL per line |
|
|
252
|
+
| `--strategy` | `-s` | `mobile` | `mobile`, `desktop`, or `both` |
|
|
253
|
+
| `--output-format` | — | `csv` | `csv`, `json`, or `both` |
|
|
254
|
+
| `--output` | `-o` | auto-timestamped | Explicit output file path |
|
|
255
|
+
| `--output-dir` | — | `./reports/` | Directory for auto-named files |
|
|
256
|
+
| `--delay` | `-d` | `1.5` | Seconds between requests |
|
|
257
|
+
| `--workers` | `-w` | `4` | Concurrent workers |
|
|
258
|
+
| `--categories` | — | `performance` | Lighthouse categories |
|
|
259
|
+
|
|
260
|
+
## Output Formats
|
|
261
|
+
|
|
262
|
+
### File naming
|
|
263
|
+
|
|
264
|
+
By default, output files use UTC timestamps:
|
|
265
|
+
|
|
266
|
+
```
|
|
267
|
+
{output_dir}/{YYYYMMDD}T{HHMMSS}Z-{strategy}.{ext}
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
Examples:
|
|
271
|
+
```
|
|
272
|
+
./reports/20260216T143022Z-mobile.csv
|
|
273
|
+
./reports/20260216T150000Z-both.json
|
|
274
|
+
./reports/20260216T143022Z-report.html
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
Use `-o` to override with an explicit path.
|
|
278
|
+
|
|
279
|
+
### CSV
|
|
280
|
+
|
|
281
|
+
Flat table with one row per (URL, strategy) pair. Columns:
|
|
282
|
+
|
|
283
|
+
| Column | Description |
|
|
284
|
+
|--------|-------------|
|
|
285
|
+
| `url` | The analyzed URL |
|
|
286
|
+
| `strategy` | `mobile` or `desktop` |
|
|
287
|
+
| `performance_score` | 0-100 Lighthouse score |
|
|
288
|
+
| `lab_fcp_ms` | First Contentful Paint (ms) |
|
|
289
|
+
| `lab_lcp_ms` | Largest Contentful Paint (ms) |
|
|
290
|
+
| `lab_cls` | Cumulative Layout Shift |
|
|
291
|
+
| `lab_speed_index_ms` | Speed Index (ms) |
|
|
292
|
+
| `lab_tbt_ms` | Total Blocking Time (ms) |
|
|
293
|
+
| `lab_tti_ms` | Time to Interactive (ms) |
|
|
294
|
+
| `field_*` | Field (CrUX) metrics (when available) |
|
|
295
|
+
| `error` | Error message if the request failed |
|
|
296
|
+
|
|
297
|
+
### JSON
|
|
298
|
+
|
|
299
|
+
Structured with metadata header:
|
|
300
|
+
|
|
301
|
+
```json
|
|
302
|
+
{
|
|
303
|
+
"metadata": {
|
|
304
|
+
"generated_at": "2026-02-16T14:30:22+00:00",
|
|
305
|
+
"total_urls": 5,
|
|
306
|
+
"strategies": ["mobile", "desktop"],
|
|
307
|
+
"tool_version": "1.0.0"
|
|
308
|
+
},
|
|
309
|
+
"results": [
|
|
310
|
+
{
|
|
311
|
+
"url": "https://example.com",
|
|
312
|
+
"strategy": "mobile",
|
|
313
|
+
"performance_score": 92,
|
|
314
|
+
"lab_metrics": { "lab_fcp_ms": 1200, "lab_lcp_ms": 1800, ... },
|
|
315
|
+
"field_metrics": { "field_lcp_ms": 2100, "field_lcp_category": "FAST", ... },
|
|
316
|
+
"error": null
|
|
317
|
+
}
|
|
318
|
+
]
|
|
319
|
+
}
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
## Metrics Reference
|
|
323
|
+
|
|
324
|
+
### Lab data (synthetic, from Lighthouse)
|
|
325
|
+
|
|
326
|
+
| Metric | Good | Needs Work | Poor |
|
|
327
|
+
|--------|------|-----------|------|
|
|
328
|
+
| First Contentful Paint | < 1.8s | 1.8s–3.0s | > 3.0s |
|
|
329
|
+
| Largest Contentful Paint | < 2.5s | 2.5s–4.0s | > 4.0s |
|
|
330
|
+
| Cumulative Layout Shift | < 0.1 | 0.1–0.25 | > 0.25 |
|
|
331
|
+
| Total Blocking Time | < 200ms | 200ms–600ms | > 600ms |
|
|
332
|
+
| Speed Index | < 3.4s | 3.4s–5.8s | > 5.8s |
|
|
333
|
+
| Time to Interactive | < 3.8s | 3.8s–7.3s | > 7.3s |
|
|
334
|
+
|
|
335
|
+
### Field data (real users, from CrUX)
|
|
336
|
+
|
|
337
|
+
Field data comes from the Chrome User Experience Report. It may not be available for low-traffic sites.
|
|
338
|
+
|
|
339
|
+
| Metric | Description |
|
|
340
|
+
|--------|-------------|
|
|
341
|
+
| FCP | First Contentful Paint — when first content appears |
|
|
342
|
+
| LCP | Largest Contentful Paint — when main content loads |
|
|
343
|
+
| CLS | Cumulative Layout Shift — visual stability |
|
|
344
|
+
| INP | Interaction to Next Paint — input responsiveness |
|
|
345
|
+
| FID | First Input Delay — (deprecated, replaced by INP) |
|
|
346
|
+
| TTFB | Time to First Byte — server response time |
|
|
347
|
+
|
|
348
|
+
## Rate Limits
|
|
349
|
+
|
|
350
|
+
| Scenario | Limit |
|
|
351
|
+
|----------|-------|
|
|
352
|
+
| Without API key | ~25 queries/100 seconds |
|
|
353
|
+
| With API key | ~25,000 queries/day (400/100 seconds) |
|
|
354
|
+
|
|
355
|
+
Tips:
|
|
356
|
+
- Use `--delay` to increase time between requests if hitting rate limits
|
|
357
|
+
- Use `--workers 1` for sequential processing (safest for rate limits)
|
|
358
|
+
- The tool retries on 429 (rate limit) responses with exponential backoff
|
|
359
|
+
|
|
360
|
+
## Cron usage
|
|
361
|
+
|
|
362
|
+
Output files auto-increment with timestamps, so cron jobs won't overwrite previous results:
|
|
363
|
+
|
|
364
|
+
```bash
|
|
365
|
+
# Every Monday at 6am UTC
|
|
366
|
+
0 6 * * 1 cd /path/to/project && pagespeed audit -f urls.txt --profile full
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
## Examples
|
|
370
|
+
|
|
371
|
+
The [`examples/`](examples/) folder contains ready-to-use configuration files for common workflows:
|
|
372
|
+
|
|
373
|
+
| Example | Description |
|
|
374
|
+
|---------|-------------|
|
|
375
|
+
| [`basic/`](examples/basic/) | Minimal config with API key, strategy, and a sample URL list |
|
|
376
|
+
| [`multi-profile/`](examples/multi-profile/) | Named profiles for quick, full, and client-report workflows |
|
|
377
|
+
| [`ci-budget/`](examples/ci-budget/) | Strict and lenient performance budgets for CI pipelines |
|
|
378
|
+
| [`sitemap-pipeline/`](examples/sitemap-pipeline/) | Sitemap auto-discovery with regex filters and section-specific profiles |
|
|
379
|
+
|
|
380
|
+
Copy any example folder into your project and edit to taste. See [`examples/README.md`](examples/README.md) for full details.
|
|
381
|
+
|
|
382
|
+
## Testing
|
|
383
|
+
|
|
384
|
+
The project includes a comprehensive test suite (102 tests across 18 test classes). All tests run offline — API calls, sitemap fetches, and file I/O are mocked.
|
|
385
|
+
|
|
386
|
+
```bash
|
|
387
|
+
# Run all tests
|
|
388
|
+
uv run test_pagespeed_insights_tool.py -v
|
|
389
|
+
|
|
390
|
+
# Run a single test class
|
|
391
|
+
uv run test_pagespeed_insights_tool.py -v TestValidateUrl
|
|
392
|
+
|
|
393
|
+
# Run a specific test method
|
|
394
|
+
uv run test_pagespeed_insights_tool.py -v TestExtractMetrics.test_full_extraction
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
## License
|
|
398
|
+
|
|
399
|
+
This project is licensed under the [MIT License](LICENSE).
|