From 5393b63cee8dc74c064bfbd39d62d800a7a380b4 Mon Sep 17 00:00:00 2001 From: jay Date: Thu, 11 Jun 2026 20:01:24 -0400 Subject: [PATCH] Telemetry: boot-slow beacon names the 3 slowest resources MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The first boot-slow capture (5763ms total, html 68ms) proved the white screen happens AFTER the shell arrives — but not which fetch eats the time. Append the 3 slowest resource entries (path, start→end, transferSize; sz0 ≈ served from SW/cache) so the next slow boot names its culprit. Reason cap 300→500 client+server to fit the detail. Co-Authored-By: Claude Opus 4.8 --- frontend/src/app.html | 12 +++++++++++- goodnews/api.py | 2 +- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/frontend/src/app.html b/frontend/src/app.html index 3d39fbc..440156d 100644 --- a/frontend/src/app.html +++ b/frontend/src/app.html @@ -42,7 +42,7 @@ function report(reason) { if (sent) return; sent = true; // one beacon per page try { - var b = new Blob([JSON.stringify({ reason: String(reason || 'unknown').slice(0, 300), + var b = new Blob([JSON.stringify({ reason: String(reason || 'unknown').slice(0, 500), path: location.pathname })], { type: 'application/json' }); navigator.sendBeacon && navigator.sendBeacon('/api/client-error', b); } catch (e) { /* best-effort telemetry */ } @@ -73,6 +73,16 @@ if (nav && nav.responseStart) detail += ' (html ' + Math.round(nav.responseStart) + 'ms)'; if (navigator.connection && navigator.connection.effectiveType) detail += ' on ' + navigator.connection.effectiveType; + // Name the culprits: the 3 slowest resource fetches so far, with + // start→end so gaps (idle/SW churn) are distinguishable from slow + // downloads. size=0 usually means it came from the SW/cache. + var res = (performance.getEntriesByType('resource') || []) + .slice().sort(function (a, b) { return b.duration - a.duration; }).slice(0, 3) + .map(function (r) { + var name = r.name.replace(location.origin, '').slice(0, 80); + return name + ' ' + Math.round(r.startTime) + '→' + Math.round(r.responseEnd) + 'ms sz' + (r.transferSize || 0); + }); + if (res.length) detail += ' | slowest: ' + res.join(' ; '); report(detail); } } catch (e) { /* timing is best-effort */ } diff --git a/goodnews/api.py b/goodnews/api.py index 47a80c9..c68e3fc 100644 --- a/goodnews/api.py +++ b/goodnews/api.py @@ -948,7 +948,7 @@ def create_app() -> FastAPI: with get_conn() as conn: conn.execute( "INSERT INTO client_errors (reason, path, user_agent, app_version) VALUES (?, ?, ?, ?)", - ((body.reason or "")[:300], (body.path or "")[:200], ua, (body.version or "")[:60]), + ((body.reason or "")[:500], (body.path or "")[:200], ua, (body.version or "")[:60]), ) conn.execute("DELETE FROM client_errors WHERE created_at < datetime('now','-14 days')") conn.commit()