summaryrefslogtreecommitdiffstats
path: root/src/qr.js
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2026-09-02 13:42:24 -0700
committerAdam Soltys <[email protected]>2026-09-02 13:42:24 -0700
commit11a7919939f30318c6f2bf81058e57e2bb604b67 (patch)
tree86fd103580bcda07099d08967a69e3f2affbfd7a /src/qr.js
parent79ebdaa0426cc9dc474a61876207ff19fbc5aa22 (diff)
downloadcoinosv3-11a7919939f30318c6f2bf81058e57e2bb604b67.tar.gz
coinosv3-11a7919939f30318c6f2bf81058e57e2bb604b67.zip
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
Co-Authored-By: Claude Fable 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01MrkLsNScXe9b6BviUSdmMr
Diffstat (limited to 'src/qr.js')
-rw-r--r--src/qr.js12
1 files changed, 11 insertions, 1 deletions
diff --git a/src/qr.js b/src/qr.js
index d02aed3..416252d 100644
--- a/src/qr.js
+++ b/src/qr.js
@@ -9,7 +9,14 @@ import qrcode from 'qrcode-generator';
// mode: pass 'Alphanumeric' for an all-uppercase QR-alphanumeric string (0-9 A-Z
// space $%*+-./:) to pack it at 5.5 bits/char instead of byte mode's 8 — a much
// smaller grid for the same data. Falls back to byte mode if the text doesn't fit.
+// Memoized: a QR is a pure function of its input, and make() runs eight
+// mask-penalty trials over the whole grid — 30ms+ on a phone for a long
+// bitcoin: URI. The receive pane used to pay that on EVERY render.
+const _memo = new Map();
export function qrSvg(text, { margin = 2, ec = 'M', mode } = {}) {
+ const key = `${ec}|${mode || ''}|${margin}|${text}`;
+ const hit = _memo.get(key);
+ if (hit) return hit;
let qr;
try {
qr = qrcode(0, ec);
@@ -33,8 +40,11 @@ export function qrSvg(text, { margin = 2, ec = 'M', mode } = {}) {
}
}
- return `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${size} ${size}" shape-rendering="crispEdges" class="qr">
+ const svg = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${size} ${size}" shape-rendering="crispEdges" class="qr">
<rect width="${size}" height="${size}" fill="#fff"/>
<path d="${path}" fill="#111"/>
</svg>`;
+ _memo.set(key, svg);
+ if (_memo.size > 24) _memo.delete(_memo.keys().next().value);
+ return svg;
}