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:
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user