Home: paint the saved brief instantly, refresh behind it (Codex)

Codex's point: edge-caching /api/brief helps anonymous visitors, but a logged-in
reader with prefs/dismissals makes it a personalized (private, origin-bound)
request — so it won't fix Jay's own "Gathering the good news…" delay. The real
fix isn't more CDN tuning, it's not blocking the first paint on the network.

The brief is already saved locally (BRIEF_VIEW_KEY). Now on the Today view we
render that saved brief immediately and refresh /api/brief in the background;
"Gathering…" only shows on a true first visit with nothing cached. A failed
background refresh stays invisible (loadToday returns if a brief is already
painted; onMount won't blank painted content) so a slow/offline origin never
wipes a good view.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
jay
2026-06-12 09:48:01 -04:00
parent ecf879fd1b
commit 854f06401f
+20 -2
View File
@@ -220,7 +220,13 @@
async function loadToday(fresh) {
const q = P.param(prefs.data);
const ex = Array.from(dismissed).join(',');
const fetched = await getJSON(`/api/brief?limit=7${q ? '&' + q : ''}${ex ? '&exclude=' + ex : ''}`);
let fetched;
try {
fetched = await getJSON(`/api/brief?limit=7${q ? '&' + q : ''}${ex ? '&exclude=' + ex : ''}`);
} catch (e) {
if (brief) return; // already showing a saved brief — a failed background refresh stays invisible
throw e; // true first load with nothing painted → let the caller surface the error
}
const view = P.loadJSON(BRIEF_VIEW_KEY, null);
const sameServerBrief =
view && view.generated_at && fetched.generated_at && view.generated_at === fetched.generated_at;
@@ -429,6 +435,18 @@
dismissed = new Set(P.loadJSON(DISMISSED_KEY, []));
refreshAuth();
trackVisit();
// Instant paint: render the last saved Today brief immediately and refresh
// it behind the scenes, so the first view never blocks on a (personalized,
// origin-bound) /api/brief request. "Gathering the good news…" then only
// shows on a genuine first visit with nothing cached yet.
if (selected === 'today') {
const cached = P.loadJSON(BRIEF_VIEW_KEY, null);
if (cached && Array.isArray(cached.items) && cached.items.length) {
brief = cached;
heroIdx = 0;
loading = false;
}
}
// Critical path: moods + categories (needed to resolve a mood/topic view)
// load in PARALLEL, then the requested view. Every getJSON times out, and
// loading ALWAYS clears in finally, so the page can never get stuck on
@@ -441,7 +459,7 @@
moods = m; topics = c.topics;
await loadView(selected);
} catch (e) {
error = 'Could not reach Upbeat Bytes.';
if (!brief) error = 'Could not reach Upbeat Bytes.'; // keep painted content if a refresh failed
} finally {
loading = false;
}