psi-snapshot
Version:
A lean CLI to fetch PageSpeed Insights and emit compact, stable snapshots for LLMs and CI.
140 lines (105 loc) • 5.76 kB
Markdown
## psi-snapshot
[](https://github.com/jlorenzetti/psi-snapshot/actions/workflows/ci.yml)
[](https://www.npmjs.com/package/psi-snapshot)
[](./LICENSE)
A lean, CLI-first tool to fetch PageSpeed Insights (PSI) results and emit compact, stable, machine-readable snapshots suitable for LLM analysis and CI reporting.
### Features
- **Compact JSON**: low-noise, stable schema optimized for LLMs
- **Mobile/Desktop**: select strategy and categories
- **Traceability**: optional raw PSI dumps
- **Batch input**: CLI args or file
- **Controls**: concurrency, delay, timeout, retries
- **CI-friendly**: deterministic naming, zero deps (Node 20+ ESM)
### Install
```bash
npm i -g psi-snapshot
# or use via npx without global install
npx psi-snapshot --help
```
### Usage
```bash
psi-snapshot <url1> [url2 ...]
psi-snapshot --file urls.txt
```
Options:
- **--strategy** <mobile|desktop> default: mobile
- **--categories** <list> comma-separated; default: performance,accessibility,best-practices,seo
- **--save-raw** also write raw PSI JSONs under snapshots/raw/
- **--out** <path> override output file path; default: snapshots/psi-snapshot-<strategy>-<timestamp>.json
- **--concurrency** <n> parallel requests (default: 3)
- **--delay-ms** <n> min delay between requests (default: 250)
- **--timeout-ms** <n> per-request timeout (default: 60000)
- **--retries** <n> for 429/5xx (default: 2; exponential backoff)
- **--fields** <google-fields> optional partial response string for PSI API (reduces payload)
- **--opportunities-limit** <n> number of top opportunities to keep (default: 8)
- **--include-details** include compact lists for key audits (off by default)
- **--details-limit** <n> max items per details list (default: 9)
- **--pretty** pretty-print output JSON (default: compact)
- **--json** also print the JSON to stdout (in addition to writing file)
- **--no-crux** skip field data (useful if unavailable)
- **--version**, **--help**
Environment:
- **GOOGLE_API_KEY** — API key for PSI. If absent, the API may still work with limited quota; prefer key.
Local usage tips (psi-snapshot does not auto-load .env):
```bash
# one-off for current shell
export GOOGLE_API_KEY=your-key
# per-command prefix
GOOGLE_API_KEY=your-key psi-snapshot https://example.com
# using dotenv-cli (dev dependency)
npx dotenv -e .env -- psi-snapshot https://example.com
```
Input sources:
- CLI args list of URLs.
- **--file** urls.txt (one URL per line, ignore blank/#comment lines).
### Snapshot Schema
The snapshot is a single JSON object keyed by URL. See `src/compact.mjs` for normalization rules.
#### Optional details (enabled via `--include-details`)
When enabled, details are emitted for all categories (Performance, Accessibility, Best Practices, SEO) with compact, top‑N lists, controlled by `--details-limit` (default 9):
- Performance details under `details.*` include: `third_party_top`, `cache_ttl_issues_top`, `network_top`, `render_blocking_top`, `unused_javascript_top`, `unused_css_top`, `unminified_css_top`, `unminified_js_top`, `text_compression_top`, `responsive_images_top`, `offscreen_images_top`, `optimized_images_top`, `modern_image_formats_top`, `redirects_top`, `legacy_javascript_top`, `unsized_images_top`, `http2_top`, `font_display_top`, `long_tasks_top`, `total_byte_weight_top`, `bootup_time_top`.
- Accessibility summaries under `details_accessibility_audits`: array of `{ id, title, score, outcome, items[] }` for non‑passing/informative audits (items show minimal `{ url|target|snippet }`).
- Best Practices summaries under `details_best_practices_audits` (same schema as above).
- SEO summaries under `details_seo_audits` (same schema as above).
Notes:
- Details are off by default to keep files small. Enable only when needed.
- We do not alter PSI outcomes; binary/numeric pass (score=1) and notApplicable are omitted to reduce noise.
### Example Commands
```bash
# Single URL, mobile (default), pretty output
psi-snapshot https://www.example.com/article --pretty
# Desktop strategy, save raw PSI, custom out path
psi-snapshot https://example.com --strategy desktop --save-raw --out snapshots/custom.json
# Batch from file, higher concurrency, partial response fields
psi-snapshot --file urls.txt --concurrency 5 \
--fields "id,analysisUTCTimestamp,lighthouseResult(requestedUrl,finalUrl,userAgent,categories(performance(score)),audits(first-contentful-paint(numericValue),largest-contentful-paint(numericValue),interactive(numericValue),total-blocking-time(numericValue),cumulative-layout-shift(numericValue),diagnostics(details/items))),loadingExperience(metrics),originLoadingExperience(metrics)"
```
### CI Example (GitHub Actions)
In this package repo we run tests on push/PR (see `.github/workflows/ci.yml`).
To schedule PSI snapshots in a consumer repo (e.g., a WordPress theme), add this workflow and adjust URLs/cron:
```yaml
name: psi-snapshot
on:
workflow_dispatch:
schedule:
- cron: '0 6 * * 1' # Mondays 06:00 UTC
jobs:
run:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
- name: Run psi-snapshot via npx
run: |
echo "https://www.example.com/" > urls.txt
npx -y psi-snapshot --file urls.txt --strategy mobile --save-raw --pretty | cat
env:
GOOGLE_API_KEY: ${{ secrets.GOOGLE_API_KEY }}
- uses: actions/upload-artifact@v4
with:
name: psi-snapshot
path: snapshots/
```
### License
MIT