perf: debounce final-state rendering and decouple LRM score fetches - #41

Merged
RaredonLab merged 1 commit into
RaredonLab:devfrom
msraredon:dev
Jun 1, 2026
Merged

perf: debounce final-state rendering and decouple LRM score fetches#41
RaredonLab merged 1 commit into
RaredonLab:devfrom
msraredon:dev

Conversation

@RaredonLab

Copy link
Copy Markdown
Owner

Addresses issue #32 and related UX feedback: the app now only computes and renders the final state after a user stops interacting, stale in-flight responses are cancelled rather than overwriting current data, and a 'Computing...' badge gives real-time feedback during any fetch.

AbortController added to all five data-fetching hooks (useEdges, useTranscripts, useCellBoundaries, useCellColors, useEdgeColors): when a new debounce fires the previous in-flight request is cancelled, so intermediate pan positions or partially-dialled settings never flash onto the canvas. Debounce for settings-driven hooks (useCellColors, useEdgeColors metadata) bumped from 150 ms to 400 ms so rapid sequential gene/LRM/colorBy changes collapse to a single server request.

useEdges is split into two independent effects:

  • Structural effect (viewport/density deps only): POSTs to /query-grouped for positions, metadata, lrm_count, and score_sum. Never re-runs on LRM filter changes.
  • Score effect (viewport + hiddenLrms deps): POSTs to new /query-scores endpoint for {edge, visible_lrm_count, visible_score_sum} only. Picks the cheaper query direction automatically — WHERE lrm IN (visible_set) when the visible set is small (e.g. user selects 10/559 LRMs → ~98% less parquet scanned), CASE WHEN NOT IN otherwise. Short-circuits entirely when no LRM filter is active.

New RenderingStatus component shows a spinner badge in the viewer corner after a 400 ms onset delay whenever any layer for that panel is fetching. Disappears immediately on completion. Works per-panel in split-screen. Loading state tracked via loadingKeys Set in Zustand store.

Addresses issue RaredonLab#32 and related UX feedback: the app now only computes
and renders the final state after a user stops interacting, stale
in-flight responses are cancelled rather than overwriting current data,
and a 'Computing...' badge gives real-time feedback during any fetch.
AbortController added to all five data-fetching hooks (useEdges,
useTranscripts, useCellBoundaries, useCellColors, useEdgeColors): when a
new debounce fires the previous in-flight request is cancelled, so
intermediate pan positions or partially-dialled settings never flash onto
the canvas. Debounce for settings-driven hooks (useCellColors,
useEdgeColors metadata) bumped from 150 ms to 400 ms so rapid sequential
gene/LRM/colorBy changes collapse to a single server request.
useEdges is split into two independent effects:
- Structural effect (viewport/density deps only): POSTs to /query-grouped
for positions, metadata, lrm_count, and score_sum. Never re-runs on
LRM filter changes.
- Score effect (viewport + hiddenLrms deps): POSTs to new /query-scores
endpoint for {edge, visible_lrm_count, visible_score_sum} only. Picks
the cheaper query direction automatically — WHERE lrm IN (visible_set)
when the visible set is small (e.g. user selects 10/559 LRMs → ~98%
less parquet scanned), CASE WHEN NOT IN otherwise. Short-circuits
entirely when no LRM filter is active.
New RenderingStatus component shows a spinner badge in the viewer corner
after a 400 ms onset delay whenever any layer for that panel is fetching.
Disappears immediately on completion. Works per-panel in split-screen.
Loading state tracked via loadingKeys Set in Zustand store.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@RaredonLab
RaredonLab merged commit dea0bc2 into RaredonLab:devJun 1, 2026
@RaredonLabRaredonLab linked an issue Jun 1, 2026 that may be closed by this pull request
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Rendering artifact during rapid pan (stale/partial tiles persist)

2 participants

@RaredonLab@msraredon
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all \u003cpre\u003e\u003ccode\u003e blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks"); } } catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); } })(); (function(){ try { var __m = "github.com"; var __re = new RegExp('^' + "github\\.com" + '
Skip to content

perf: debounce final-state rendering and decouple LRM score fetches - #41

Merged
RaredonLab merged 1 commit into
RaredonLab:devfrom
msraredon:dev
Jun 1, 2026
Merged

perf: debounce final-state rendering and decouple LRM score fetches#41
RaredonLab merged 1 commit into
RaredonLab:devfrom
msraredon:dev

Conversation

@RaredonLab

Copy link
Copy Markdown
Owner

Addresses issue #32 and related UX feedback: the app now only computes and renders the final state after a user stops interacting, stale in-flight responses are cancelled rather than overwriting current data, and a 'Computing...' badge gives real-time feedback during any fetch.

AbortController added to all five data-fetching hooks (useEdges, useTranscripts, useCellBoundaries, useCellColors, useEdgeColors): when a new debounce fires the previous in-flight request is cancelled, so intermediate pan positions or partially-dialled settings never flash onto the canvas. Debounce for settings-driven hooks (useCellColors, useEdgeColors metadata) bumped from 150 ms to 400 ms so rapid sequential gene/LRM/colorBy changes collapse to a single server request.

useEdges is split into two independent effects:

  • Structural effect (viewport/density deps only): POSTs to /query-grouped for positions, metadata, lrm_count, and score_sum. Never re-runs on LRM filter changes.
  • Score effect (viewport + hiddenLrms deps): POSTs to new /query-scores endpoint for {edge, visible_lrm_count, visible_score_sum} only. Picks the cheaper query direction automatically — WHERE lrm IN (visible_set) when the visible set is small (e.g. user selects 10/559 LRMs → ~98% less parquet scanned), CASE WHEN NOT IN otherwise. Short-circuits entirely when no LRM filter is active.

New RenderingStatus component shows a spinner badge in the viewer corner after a 400 ms onset delay whenever any layer for that panel is fetching. Disappears immediately on completion. Works per-panel in split-screen. Loading state tracked via loadingKeys Set in Zustand store.

Addresses issue RaredonLab#32 and related UX feedback: the app now only computes
and renders the final state after a user stops interacting, stale
in-flight responses are cancelled rather than overwriting current data,
and a 'Computing...' badge gives real-time feedback during any fetch.
AbortController added to all five data-fetching hooks (useEdges,
useTranscripts, useCellBoundaries, useCellColors, useEdgeColors): when a
new debounce fires the previous in-flight request is cancelled, so
intermediate pan positions or partially-dialled settings never flash onto
the canvas. Debounce for settings-driven hooks (useCellColors,
useEdgeColors metadata) bumped from 150 ms to 400 ms so rapid sequential
gene/LRM/colorBy changes collapse to a single server request.
useEdges is split into two independent effects:
- Structural effect (viewport/density deps only): POSTs to /query-grouped
for positions, metadata, lrm_count, and score_sum. Never re-runs on
LRM filter changes.
- Score effect (viewport + hiddenLrms deps): POSTs to new /query-scores
endpoint for {edge, visible_lrm_count, visible_score_sum} only. Picks
the cheaper query direction automatically — WHERE lrm IN (visible_set)
when the visible set is small (e.g. user selects 10/559 LRMs → ~98%
less parquet scanned), CASE WHEN NOT IN otherwise. Short-circuits
entirely when no LRM filter is active.
New RenderingStatus component shows a spinner badge in the viewer corner
after a 400 ms onset delay whenever any layer for that panel is fetching.
Disappears immediately on completion. Works per-panel in split-screen.
Loading state tracked via loadingKeys Set in Zustand store.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@RaredonLab
RaredonLab merged commit dea0bc2 into RaredonLab:devJun 1, 2026
@RaredonLabRaredonLab linked an issue Jun 1, 2026 that may be closed by this pull request
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Rendering artifact during rapid pan (stale/partial tiles persist)

2 participants

@RaredonLab@msraredon
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

perf: debounce final-state rendering and decouple LRM score fetches - #41

Merged
RaredonLab merged 1 commit into
RaredonLab:devfrom
msraredon:dev
Jun 1, 2026
Merged

perf: debounce final-state rendering and decouple LRM score fetches#41
RaredonLab merged 1 commit into
RaredonLab:devfrom
msraredon:dev

Conversation

@RaredonLab

Copy link
Copy Markdown
Owner

Addresses issue #32 and related UX feedback: the app now only computes and renders the final state after a user stops interacting, stale in-flight responses are cancelled rather than overwriting current data, and a 'Computing...' badge gives real-time feedback during any fetch.

AbortController added to all five data-fetching hooks (useEdges, useTranscripts, useCellBoundaries, useCellColors, useEdgeColors): when a new debounce fires the previous in-flight request is cancelled, so intermediate pan positions or partially-dialled settings never flash onto the canvas. Debounce for settings-driven hooks (useCellColors, useEdgeColors metadata) bumped from 150 ms to 400 ms so rapid sequential gene/LRM/colorBy changes collapse to a single server request.

useEdges is split into two independent effects:

  • Structural effect (viewport/density deps only): POSTs to /query-grouped for positions, metadata, lrm_count, and score_sum. Never re-runs on LRM filter changes.
  • Score effect (viewport + hiddenLrms deps): POSTs to new /query-scores endpoint for {edge, visible_lrm_count, visible_score_sum} only. Picks the cheaper query direction automatically — WHERE lrm IN (visible_set) when the visible set is small (e.g. user selects 10/559 LRMs → ~98% less parquet scanned), CASE WHEN NOT IN otherwise. Short-circuits entirely when no LRM filter is active.

New RenderingStatus component shows a spinner badge in the viewer corner after a 400 ms onset delay whenever any layer for that panel is fetching. Disappears immediately on completion. Works per-panel in split-screen. Loading state tracked via loadingKeys Set in Zustand store.

Addresses issue RaredonLab#32 and related UX feedback: the app now only computes
and renders the final state after a user stops interacting, stale
in-flight responses are cancelled rather than overwriting current data,
and a 'Computing...' badge gives real-time feedback during any fetch.
AbortController added to all five data-fetching hooks (useEdges,
useTranscripts, useCellBoundaries, useCellColors, useEdgeColors): when a
new debounce fires the previous in-flight request is cancelled, so
intermediate pan positions or partially-dialled settings never flash onto
the canvas. Debounce for settings-driven hooks (useCellColors,
useEdgeColors metadata) bumped from 150 ms to 400 ms so rapid sequential
gene/LRM/colorBy changes collapse to a single server request.
useEdges is split into two independent effects:
- Structural effect (viewport/density deps only): POSTs to /query-grouped
for positions, metadata, lrm_count, and score_sum. Never re-runs on
LRM filter changes.
- Score effect (viewport + hiddenLrms deps): POSTs to new /query-scores
endpoint for {edge, visible_lrm_count, visible_score_sum} only. Picks
the cheaper query direction automatically — WHERE lrm IN (visible_set)
when the visible set is small (e.g. user selects 10/559 LRMs → ~98%
less parquet scanned), CASE WHEN NOT IN otherwise. Short-circuits
entirely when no LRM filter is active.
New RenderingStatus component shows a spinner badge in the viewer corner
after a 400 ms onset delay whenever any layer for that panel is fetching.
Disappears immediately on completion. Works per-panel in split-screen.
Loading state tracked via loadingKeys Set in Zustand store.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@RaredonLab
RaredonLab merged commit dea0bc2 into RaredonLab:devJun 1, 2026
@RaredonLabRaredonLab linked an issue Jun 1, 2026 that may be closed by this pull request
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Rendering artifact during rapid pan (stale/partial tiles persist)

2 participants

@RaredonLab@msraredon
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length \u003e 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

perf: debounce final-state rendering and decouple LRM score fetches - #41

Merged
RaredonLab merged 1 commit into
RaredonLab:devfrom
msraredon:dev
Jun 1, 2026
Merged

perf: debounce final-state rendering and decouple LRM score fetches#41
RaredonLab merged 1 commit into
RaredonLab:devfrom
msraredon:dev

Conversation

@RaredonLab

Copy link
Copy Markdown
Owner

Addresses issue #32 and related UX feedback: the app now only computes and renders the final state after a user stops interacting, stale in-flight responses are cancelled rather than overwriting current data, and a 'Computing...' badge gives real-time feedback during any fetch.

AbortController added to all five data-fetching hooks (useEdges, useTranscripts, useCellBoundaries, useCellColors, useEdgeColors): when a new debounce fires the previous in-flight request is cancelled, so intermediate pan positions or partially-dialled settings never flash onto the canvas. Debounce for settings-driven hooks (useCellColors, useEdgeColors metadata) bumped from 150 ms to 400 ms so rapid sequential gene/LRM/colorBy changes collapse to a single server request.

useEdges is split into two independent effects:

  • Structural effect (viewport/density deps only): POSTs to /query-grouped for positions, metadata, lrm_count, and score_sum. Never re-runs on LRM filter changes.
  • Score effect (viewport + hiddenLrms deps): POSTs to new /query-scores endpoint for {edge, visible_lrm_count, visible_score_sum} only. Picks the cheaper query direction automatically — WHERE lrm IN (visible_set) when the visible set is small (e.g. user selects 10/559 LRMs → ~98% less parquet scanned), CASE WHEN NOT IN otherwise. Short-circuits entirely when no LRM filter is active.

New RenderingStatus component shows a spinner badge in the viewer corner after a 400 ms onset delay whenever any layer for that panel is fetching. Disappears immediately on completion. Works per-panel in split-screen. Loading state tracked via loadingKeys Set in Zustand store.

Addresses issue RaredonLab#32 and related UX feedback: the app now only computes
and renders the final state after a user stops interacting, stale
in-flight responses are cancelled rather than overwriting current data,
and a 'Computing...' badge gives real-time feedback during any fetch.
AbortController added to all five data-fetching hooks (useEdges,
useTranscripts, useCellBoundaries, useCellColors, useEdgeColors): when a
new debounce fires the previous in-flight request is cancelled, so
intermediate pan positions or partially-dialled settings never flash onto
the canvas. Debounce for settings-driven hooks (useCellColors,
useEdgeColors metadata) bumped from 150 ms to 400 ms so rapid sequential
gene/LRM/colorBy changes collapse to a single server request.
useEdges is split into two independent effects:
- Structural effect (viewport/density deps only): POSTs to /query-grouped
for positions, metadata, lrm_count, and score_sum. Never re-runs on
LRM filter changes.
- Score effect (viewport + hiddenLrms deps): POSTs to new /query-scores
endpoint for {edge, visible_lrm_count, visible_score_sum} only. Picks
the cheaper query direction automatically — WHERE lrm IN (visible_set)
when the visible set is small (e.g. user selects 10/559 LRMs → ~98%
less parquet scanned), CASE WHEN NOT IN otherwise. Short-circuits
entirely when no LRM filter is active.
New RenderingStatus component shows a spinner badge in the viewer corner
after a 400 ms onset delay whenever any layer for that panel is fetching.
Disappears immediately on completion. Works per-panel in split-screen.
Loading state tracked via loadingKeys Set in Zustand store.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@RaredonLab
RaredonLab merged commit dea0bc2 into RaredonLab:devJun 1, 2026
@RaredonLabRaredonLab linked an issue Jun 1, 2026 that may be closed by this pull request
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Rendering artifact during rapid pan (stale/partial tiles persist)

2 participants

@RaredonLab@msraredon
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

perf: debounce final-state rendering and decouple LRM score fetches - #41

Merged
RaredonLab merged 1 commit into
RaredonLab:devfrom
msraredon:dev
Jun 1, 2026
Merged

perf: debounce final-state rendering and decouple LRM score fetches#41
RaredonLab merged 1 commit into
RaredonLab:devfrom
msraredon:dev

Conversation

@RaredonLab

Copy link
Copy Markdown
Owner

Addresses issue #32 and related UX feedback: the app now only computes and renders the final state after a user stops interacting, stale in-flight responses are cancelled rather than overwriting current data, and a 'Computing...' badge gives real-time feedback during any fetch.

AbortController added to all five data-fetching hooks (useEdges, useTranscripts, useCellBoundaries, useCellColors, useEdgeColors): when a new debounce fires the previous in-flight request is cancelled, so intermediate pan positions or partially-dialled settings never flash onto the canvas. Debounce for settings-driven hooks (useCellColors, useEdgeColors metadata) bumped from 150 ms to 400 ms so rapid sequential gene/LRM/colorBy changes collapse to a single server request.

useEdges is split into two independent effects:

  • Structural effect (viewport/density deps only): POSTs to /query-grouped for positions, metadata, lrm_count, and score_sum. Never re-runs on LRM filter changes.
  • Score effect (viewport + hiddenLrms deps): POSTs to new /query-scores endpoint for {edge, visible_lrm_count, visible_score_sum} only. Picks the cheaper query direction automatically — WHERE lrm IN (visible_set) when the visible set is small (e.g. user selects 10/559 LRMs → ~98% less parquet scanned), CASE WHEN NOT IN otherwise. Short-circuits entirely when no LRM filter is active.

New RenderingStatus component shows a spinner badge in the viewer corner after a 400 ms onset delay whenever any layer for that panel is fetching. Disappears immediately on completion. Works per-panel in split-screen. Loading state tracked via loadingKeys Set in Zustand store.

Addresses issue RaredonLab#32 and related UX feedback: the app now only computes
and renders the final state after a user stops interacting, stale
in-flight responses are cancelled rather than overwriting current data,
and a 'Computing...' badge gives real-time feedback during any fetch.
AbortController added to all five data-fetching hooks (useEdges,
useTranscripts, useCellBoundaries, useCellColors, useEdgeColors): when a
new debounce fires the previous in-flight request is cancelled, so
intermediate pan positions or partially-dialled settings never flash onto
the canvas. Debounce for settings-driven hooks (useCellColors,
useEdgeColors metadata) bumped from 150 ms to 400 ms so rapid sequential
gene/LRM/colorBy changes collapse to a single server request.
useEdges is split into two independent effects:
- Structural effect (viewport/density deps only): POSTs to /query-grouped
for positions, metadata, lrm_count, and score_sum. Never re-runs on
LRM filter changes.
- Score effect (viewport + hiddenLrms deps): POSTs to new /query-scores
endpoint for {edge, visible_lrm_count, visible_score_sum} only. Picks
the cheaper query direction automatically — WHERE lrm IN (visible_set)
when the visible set is small (e.g. user selects 10/559 LRMs → ~98%
less parquet scanned), CASE WHEN NOT IN otherwise. Short-circuits
entirely when no LRM filter is active.
New RenderingStatus component shows a spinner badge in the viewer corner
after a 400 ms onset delay whenever any layer for that panel is fetching.
Disappears immediately on completion. Works per-panel in split-screen.
Loading state tracked via loadingKeys Set in Zustand store.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@RaredonLab
RaredonLab merged commit dea0bc2 into RaredonLab:devJun 1, 2026
@RaredonLabRaredonLab linked an issue Jun 1, 2026 that may be closed by this pull request
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Rendering artifact during rapid pan (stale/partial tiles persist)

2 participants

@RaredonLab@msraredon
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

perf: debounce final-state rendering and decouple LRM score fetches - #41

Merged
RaredonLab merged 1 commit into
RaredonLab:devfrom
msraredon:dev
Jun 1, 2026
Merged

perf: debounce final-state rendering and decouple LRM score fetches#41
RaredonLab merged 1 commit into
RaredonLab:devfrom
msraredon:dev

Conversation

@RaredonLab

Copy link
Copy Markdown
Owner

Addresses issue #32 and related UX feedback: the app now only computes and renders the final state after a user stops interacting, stale in-flight responses are cancelled rather than overwriting current data, and a 'Computing...' badge gives real-time feedback during any fetch.

AbortController added to all five data-fetching hooks (useEdges, useTranscripts, useCellBoundaries, useCellColors, useEdgeColors): when a new debounce fires the previous in-flight request is cancelled, so intermediate pan positions or partially-dialled settings never flash onto the canvas. Debounce for settings-driven hooks (useCellColors, useEdgeColors metadata) bumped from 150 ms to 400 ms so rapid sequential gene/LRM/colorBy changes collapse to a single server request.

useEdges is split into two independent effects:

  • Structural effect (viewport/density deps only): POSTs to /query-grouped for positions, metadata, lrm_count, and score_sum. Never re-runs on LRM filter changes.
  • Score effect (viewport + hiddenLrms deps): POSTs to new /query-scores endpoint for {edge, visible_lrm_count, visible_score_sum} only. Picks the cheaper query direction automatically — WHERE lrm IN (visible_set) when the visible set is small (e.g. user selects 10/559 LRMs → ~98% less parquet scanned), CASE WHEN NOT IN otherwise. Short-circuits entirely when no LRM filter is active.

New RenderingStatus component shows a spinner badge in the viewer corner after a 400 ms onset delay whenever any layer for that panel is fetching. Disappears immediately on completion. Works per-panel in split-screen. Loading state tracked via loadingKeys Set in Zustand store.

Addresses issue RaredonLab#32 and related UX feedback: the app now only computes
and renders the final state after a user stops interacting, stale
in-flight responses are cancelled rather than overwriting current data,
and a 'Computing...' badge gives real-time feedback during any fetch.
AbortController added to all five data-fetching hooks (useEdges,
useTranscripts, useCellBoundaries, useCellColors, useEdgeColors): when a
new debounce fires the previous in-flight request is cancelled, so
intermediate pan positions or partially-dialled settings never flash onto
the canvas. Debounce for settings-driven hooks (useCellColors,
useEdgeColors metadata) bumped from 150 ms to 400 ms so rapid sequential
gene/LRM/colorBy changes collapse to a single server request.
useEdges is split into two independent effects:
- Structural effect (viewport/density deps only): POSTs to /query-grouped
for positions, metadata, lrm_count, and score_sum. Never re-runs on
LRM filter changes.
- Score effect (viewport + hiddenLrms deps): POSTs to new /query-scores
endpoint for {edge, visible_lrm_count, visible_score_sum} only. Picks
the cheaper query direction automatically — WHERE lrm IN (visible_set)
when the visible set is small (e.g. user selects 10/559 LRMs → ~98%
less parquet scanned), CASE WHEN NOT IN otherwise. Short-circuits
entirely when no LRM filter is active.
New RenderingStatus component shows a spinner badge in the viewer corner
after a 400 ms onset delay whenever any layer for that panel is fetching.
Disappears immediately on completion. Works per-panel in split-screen.
Loading state tracked via loadingKeys Set in Zustand store.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@RaredonLab
RaredonLab merged commit dea0bc2 into RaredonLab:devJun 1, 2026
@RaredonLabRaredonLab linked an issue Jun 1, 2026 that may be closed by this pull request
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Rendering artifact during rapid pan (stale/partial tiles persist)

2 participants

@RaredonLab@msraredon
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

perf: debounce final-state rendering and decouple LRM score fetches - #41

Merged
RaredonLab merged 1 commit into
RaredonLab:devfrom
msraredon:dev
Jun 1, 2026
Merged

perf: debounce final-state rendering and decouple LRM score fetches#41
RaredonLab merged 1 commit into
RaredonLab:devfrom
msraredon:dev

Conversation

@RaredonLab

Copy link
Copy Markdown
Owner

Addresses issue #32 and related UX feedback: the app now only computes and renders the final state after a user stops interacting, stale in-flight responses are cancelled rather than overwriting current data, and a 'Computing...' badge gives real-time feedback during any fetch.

AbortController added to all five data-fetching hooks (useEdges, useTranscripts, useCellBoundaries, useCellColors, useEdgeColors): when a new debounce fires the previous in-flight request is cancelled, so intermediate pan positions or partially-dialled settings never flash onto the canvas. Debounce for settings-driven hooks (useCellColors, useEdgeColors metadata) bumped from 150 ms to 400 ms so rapid sequential gene/LRM/colorBy changes collapse to a single server request.

useEdges is split into two independent effects:

  • Structural effect (viewport/density deps only): POSTs to /query-grouped for positions, metadata, lrm_count, and score_sum. Never re-runs on LRM filter changes.
  • Score effect (viewport + hiddenLrms deps): POSTs to new /query-scores endpoint for {edge, visible_lrm_count, visible_score_sum} only. Picks the cheaper query direction automatically — WHERE lrm IN (visible_set) when the visible set is small (e.g. user selects 10/559 LRMs → ~98% less parquet scanned), CASE WHEN NOT IN otherwise. Short-circuits entirely when no LRM filter is active.

New RenderingStatus component shows a spinner badge in the viewer corner after a 400 ms onset delay whenever any layer for that panel is fetching. Disappears immediately on completion. Works per-panel in split-screen. Loading state tracked via loadingKeys Set in Zustand store.

Addresses issue RaredonLab#32 and related UX feedback: the app now only computes
and renders the final state after a user stops interacting, stale
in-flight responses are cancelled rather than overwriting current data,
and a 'Computing...' badge gives real-time feedback during any fetch.
AbortController added to all five data-fetching hooks (useEdges,
useTranscripts, useCellBoundaries, useCellColors, useEdgeColors): when a
new debounce fires the previous in-flight request is cancelled, so
intermediate pan positions or partially-dialled settings never flash onto
the canvas. Debounce for settings-driven hooks (useCellColors,
useEdgeColors metadata) bumped from 150 ms to 400 ms so rapid sequential
gene/LRM/colorBy changes collapse to a single server request.
useEdges is split into two independent effects:
- Structural effect (viewport/density deps only): POSTs to /query-grouped
for positions, metadata, lrm_count, and score_sum. Never re-runs on
LRM filter changes.
- Score effect (viewport + hiddenLrms deps): POSTs to new /query-scores
endpoint for {edge, visible_lrm_count, visible_score_sum} only. Picks
the cheaper query direction automatically — WHERE lrm IN (visible_set)
when the visible set is small (e.g. user selects 10/559 LRMs → ~98%
less parquet scanned), CASE WHEN NOT IN otherwise. Short-circuits
entirely when no LRM filter is active.
New RenderingStatus component shows a spinner badge in the viewer corner
after a 400 ms onset delay whenever any layer for that panel is fetching.
Disappears immediately on completion. Works per-panel in split-screen.
Loading state tracked via loadingKeys Set in Zustand store.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@RaredonLab
RaredonLab merged commit dea0bc2 into RaredonLab:devJun 1, 2026
@RaredonLabRaredonLab linked an issue Jun 1, 2026 that may be closed by this pull request
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Rendering artifact during rapid pan (stale/partial tiles persist)

2 participants

@RaredonLab@msraredon
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

perf: debounce final-state rendering and decouple LRM score fetches - #41

Merged
RaredonLab merged 1 commit into
RaredonLab:devfrom
msraredon:dev
Jun 1, 2026
Merged

perf: debounce final-state rendering and decouple LRM score fetches#41
RaredonLab merged 1 commit into
RaredonLab:devfrom
msraredon:dev

Conversation

@RaredonLab

Copy link
Copy Markdown
Owner

Addresses issue #32 and related UX feedback: the app now only computes and renders the final state after a user stops interacting, stale in-flight responses are cancelled rather than overwriting current data, and a 'Computing...' badge gives real-time feedback during any fetch.

AbortController added to all five data-fetching hooks (useEdges, useTranscripts, useCellBoundaries, useCellColors, useEdgeColors): when a new debounce fires the previous in-flight request is cancelled, so intermediate pan positions or partially-dialled settings never flash onto the canvas. Debounce for settings-driven hooks (useCellColors, useEdgeColors metadata) bumped from 150 ms to 400 ms so rapid sequential gene/LRM/colorBy changes collapse to a single server request.

useEdges is split into two independent effects:

  • Structural effect (viewport/density deps only): POSTs to /query-grouped for positions, metadata, lrm_count, and score_sum. Never re-runs on LRM filter changes.
  • Score effect (viewport + hiddenLrms deps): POSTs to new /query-scores endpoint for {edge, visible_lrm_count, visible_score_sum} only. Picks the cheaper query direction automatically — WHERE lrm IN (visible_set) when the visible set is small (e.g. user selects 10/559 LRMs → ~98% less parquet scanned), CASE WHEN NOT IN otherwise. Short-circuits entirely when no LRM filter is active.

New RenderingStatus component shows a spinner badge in the viewer corner after a 400 ms onset delay whenever any layer for that panel is fetching. Disappears immediately on completion. Works per-panel in split-screen. Loading state tracked via loadingKeys Set in Zustand store.

Addresses issue RaredonLab#32 and related UX feedback: the app now only computes
and renders the final state after a user stops interacting, stale
in-flight responses are cancelled rather than overwriting current data,
and a 'Computing...' badge gives real-time feedback during any fetch.
AbortController added to all five data-fetching hooks (useEdges,
useTranscripts, useCellBoundaries, useCellColors, useEdgeColors): when a
new debounce fires the previous in-flight request is cancelled, so
intermediate pan positions or partially-dialled settings never flash onto
the canvas. Debounce for settings-driven hooks (useCellColors,
useEdgeColors metadata) bumped from 150 ms to 400 ms so rapid sequential
gene/LRM/colorBy changes collapse to a single server request.
useEdges is split into two independent effects:
- Structural effect (viewport/density deps only): POSTs to /query-grouped
for positions, metadata, lrm_count, and score_sum. Never re-runs on
LRM filter changes.
- Score effect (viewport + hiddenLrms deps): POSTs to new /query-scores
endpoint for {edge, visible_lrm_count, visible_score_sum} only. Picks
the cheaper query direction automatically — WHERE lrm IN (visible_set)
when the visible set is small (e.g. user selects 10/559 LRMs → ~98%
less parquet scanned), CASE WHEN NOT IN otherwise. Short-circuits
entirely when no LRM filter is active.
New RenderingStatus component shows a spinner badge in the viewer corner
after a 400 ms onset delay whenever any layer for that panel is fetching.
Disappears immediately on completion. Works per-panel in split-screen.
Loading state tracked via loadingKeys Set in Zustand store.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@RaredonLab
RaredonLab merged commit dea0bc2 into RaredonLab:devJun 1, 2026
@RaredonLabRaredonLab linked an issue Jun 1, 2026 that may be closed by this pull request
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Rendering artifact during rapid pan (stale/partial tiles persist)

2 participants

@RaredonLab@msraredon