mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-16 22:26:16 -08:00
Deduplicate initial resources by request URL rather than by file, so a file referenced twice with different query strings is counted twice, as the browser fetches it; fragments are still ignored. Each resource now carries both its file path and its request URL. Describe the CI ratchet as the goal of the loop rather than as existing enforcement until the baseline and job PRs merge. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
64 lines
3.5 KiB
Markdown
64 lines
3.5 KiB
Markdown
# Performance journeys and the CI ratchet
|
|
|
|
IPTVnator measures performance through a small set of everyday user journeys.
|
|
Each journey has deterministic counters that are asserted exactly, and
|
|
wall-clock timings that are recorded as evidence. Counters are meant to be
|
|
ratcheted in CI: a committed baseline that may only be lowered, and only with
|
|
the measured output as evidence. This document is the contract for that loop;
|
|
`tools/performance/` holds the scripts. The measurement script lands first;
|
|
the baseline file and the CI job follow in their own PRs (#1693, #1694), so
|
|
until they merge the reported number is informational, not enforced.
|
|
|
|
## Journeys
|
|
|
|
| Journey | Start | End |
|
|
| ---------------- | -------------------------------------------- | ----------------------------------------------------------------------------- |
|
|
| J1 `launch` | Electron process spawn | first playlist or portal card rendered on `/workspace`, inline splash removed |
|
|
| J2 `open-source` | click on a portal card | live category list and first channel page painted |
|
|
| J3 `playback` | click on a channel | HTML5 `playing` event |
|
|
| J4 `search` | six-character query typed into global search | results list settled |
|
|
|
|
Only the J1 counter `renderer.initialBytes` is instrumented today. The other
|
|
journeys and counters follow the plan in `.plans/` and are added one thread at
|
|
a time; each thread names its journey and counter in the PR description.
|
|
|
|
## `renderer.initialBytes`
|
|
|
|
The bytes a browser fetches before Angular can bootstrap, read from the built
|
|
`dist/apps/web/index.html`:
|
|
|
|
- `index.html` itself,
|
|
- every same-origin `<script src>`, including `assets/app-config.js`,
|
|
- every `<link rel="stylesheet">`,
|
|
- every `<link rel="modulepreload">` chunk.
|
|
|
|
Manifest, icons, external URLs and lazy chunks are not counted. A file that
|
|
`index.html` references but the build did not emit is an error, never zero
|
|
bytes. The value is raw (uncompressed) size, which is what the renderer parses;
|
|
it matches the "Initial total" line of the Angular build output.
|
|
|
|
```bash
|
|
pnpm nx build web # production configuration
|
|
pnpm run perf:initial-bytes # human-readable breakdown
|
|
pnpm run perf:initial-bytes -- --json # machine-readable breakdown
|
|
pnpm run perf:initial-bytes -- --summary dist/performance/journey-summary.json
|
|
```
|
|
|
|
`--summary` writes the journey summary shape (`journeys.<journey>.counters`)
|
|
that the ratchet checker consumes. `--dist <dir>` points the script at another
|
|
build output, for example the `electron-performance` configuration.
|
|
|
|
The measurement script is `tools/performance/measure-initial-bytes.mjs`; its
|
|
Node tests run with `pnpm nx test performance-tools` (Tier B in the coverage
|
|
policy) and lint with `pnpm nx lint performance-tools`.
|
|
|
|
## Adding a counter
|
|
|
|
1. Produce the value from the built output or from a deterministic probe, not
|
|
from source heuristics. Missing inputs must fail the measurement.
|
|
2. Emit it under `journeys.<journey>.counters.<name>` in the summary JSON.
|
|
3. Cover the extraction and the failure modes with `node --test` and register
|
|
the test file in `tools/performance/project.json`.
|
|
4. Validate the counter before it becomes a guardrail: one PR must show that
|
|
lowering it moved wall-clock in the same journey.
|