From 11a7919939f30318c6f2bf81058e57e2bb604b67 Mon Sep 17 00:00:00 2001 From: Adam Soltys Date: Wed, 2 Sep 2026 13:42:24 -0700 Subject: Three render hogs put on a leash for the sluggish-tabs hunt: qrSvg is memoized (make() runs eight mask trials over a version-20 grid — 30ms+ per call on a phone, paid on EVERY render of the receive pane), the header's unread count reuses its answer behind a revision counter bumped only when messages or read-marks actually change, and ark's history list rebuilds at most every 1.5s instead of per repaint MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01MrkLsNScXe9b6BviUSdmMr --- src/features/ark.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'src/features/ark.js') diff --git a/src/features/ark.js b/src/features/ark.js index 97f730a..72624b4 100644 --- a/src/features/ark.js +++ b/src/features/ark.js @@ -2913,6 +2913,19 @@ export function arkFeature(ctx) { historyEntries() { const s = arkStateNow(); if (!s) return []; + // Memoized briefly: this rebuilds, sorts, and dedupes the whole + // movements list plus the accounted-inputs set — fine once, wasteful + // on every repaint. Movements only change through saves that trigger + // a render themselves, so a short reuse window costs nothing visible. + const key = `${(s.movements || []).length}:${(s.actions || []).length}`; + if (this._histMemo && this._histMemo.key === key && Date.now() - this._histMemo.t < 1500) { + return this._histMemo.val; + } + const val = this._histBuild(s); + this._histMemo = { key, t: Date.now(), val }; + return val; + }, + _histBuild(s) { // In-flight exits are payments the user made — they belong in history // as pending records, not on a monitoring page nobody thinks to visit. const exits = (s.actions || []) -- cgit v1.2.3