| 1 | package main |
| 2 | |
| 3 | // uiPerfSignalAllowlist is the closed set of frontend latency signals. Values |
| 4 | // arrive pre-bucketed from lib/uiPerf.ts; dropping anything else keeps webview |
| 5 | // input from widening telemetry cardinality. |
| 6 | var uiPerfSignalAllowlist = map[string]bool{ |
| 7 | "ui_bridge_events_rate": true, |
| 8 | "ui_state_commit_rate": true, |
| 9 | "ui_stream_paint_p95": true, |
| 10 | "ui_frame_p95": true, |
| 11 | "ui_slow_frames": true, |
| 12 | "ui_input_latency_p95": true, |
| 13 | "ui_markdown_p95": true, |
| 14 | "ui_long_tasks": true, |
| 15 | "ui_dom_nodes": true, |
| 16 | "ui_js_heap": true, |
| 17 | } |
| 18 | |
| 19 | func filterUIPerfSignals(in map[string]string) map[string]string { |
| 20 | out := make(map[string]string, len(in)) |
| 21 | for signal, bucket := range in { |
| 22 | if uiPerfSignalAllowlist[signal] && bucket != "" { |
| 23 | out[signal] = bucket |
| 24 | } |
| 25 | } |
| 26 | return out |
| 27 | } |
| 28 | |
| 29 | // RecordUIPerf records one turn's frontend latency summary as anonymous |
| 30 | // (signal, bucket) counters — same privacy posture as the event-stream |
| 31 | // metrics: bounded enums only, never content. |
| 32 | func (a *App) RecordUIPerf(signals map[string]string) { |
| 33 | for signal, bucket := range filterUIPerfSignals(signals) { |
| 34 | a.recordDiagnosticMetric(signal, bucket) |
| 35 | } |
| 36 | } |
| 37 |