mirror of
https://github.com/nesquena/hermes-webui.git
synced 2026-05-28 04:30:18 +00:00
perf(ui): cache visWithIdx to skip O(N) scan on render window expansion
This commit is contained in:
+23
-4
@@ -265,10 +265,15 @@ function _statusCardHtml(card){
|
||||
const MESSAGE_RENDER_WINDOW_DEFAULT=50;
|
||||
let _messageRenderWindowSid=null;
|
||||
let _messageRenderWindowSize=MESSAGE_RENDER_WINDOW_DEFAULT;
|
||||
// Cached visWithIdx array — invalidated when S.messages.length changes.
|
||||
let _visWithIdxCache=null;
|
||||
let _visWithIdxCacheLen=0;
|
||||
function _resetMessageRenderWindow(sid){
|
||||
_messageRenderWindowSid=sid||null;
|
||||
_messageRenderWindowSize=MESSAGE_RENDER_WINDOW_DEFAULT;
|
||||
_clearRenderCache();
|
||||
_visWithIdxCache=null;
|
||||
_visWithIdxCacheLen=0;
|
||||
}
|
||||
|
||||
// ── renderMd / _renderUserFencedBlocks cache ──────────────────────────────
|
||||
@@ -6120,15 +6125,29 @@ function renderMessages(options){
|
||||
? (()=>{const row=document.createElement('div');row.innerHTML=`<div class="compression-turn"><div class="compression-turn-blocks">${_compressionReferenceCardHtml(referenceText,false)}${_preservedCompressionTaskListCardsHtml(preservedCompressionTaskMessages)}</div></div>`;return row.firstElementChild;})()
|
||||
: null;
|
||||
let preservedCompressionTaskCardsAttached=!!referenceNode;
|
||||
const visWithIdx=[];
|
||||
// Cache visWithIdx so expanding the render window (Load earlier) doesn't
|
||||
// re-scan S.messages from scratch. Invalidate only when the message array
|
||||
// length changes — i.e. new messages arrived or session was truncated.
|
||||
if(!_visWithIdxCache || _visWithIdxCacheLen !== S.messages.length){
|
||||
const rebuilt=[];
|
||||
let ri=0;
|
||||
for(const m of S.messages){
|
||||
if(!m||!m.role||m.role==='tool'){ri++;continue;}
|
||||
if(_isPreservedCompressionTaskListMessage(m)){ri++;continue;}
|
||||
const hasTc=Array.isArray(m.tool_calls)&&m.tool_calls.length>0;
|
||||
const hasTu=Array.isArray(m.content)&&m.content.some(p=>p&&p.type==='tool_use');
|
||||
if(msgContent(m)||m._statusCard||m.attachments?.length||(m.role==='assistant'&&(hasTc||hasTu||_messageHasReasoningPayload(m)))) rebuilt.push({m,rawIdx:ri});
|
||||
ri++;
|
||||
}
|
||||
_visWithIdxCache=rebuilt;
|
||||
_visWithIdxCacheLen=S.messages.length;
|
||||
}
|
||||
const visWithIdx=_visWithIdxCache;
|
||||
const preservedCompressionRawIdxs=[];
|
||||
let rawIdx=0;
|
||||
for(const m of S.messages){
|
||||
if(!m||!m.role||m.role==='tool'){rawIdx++;continue;}
|
||||
if(_isPreservedCompressionTaskListMessage(m)){preservedCompressionRawIdxs.push(rawIdx);rawIdx++;continue;}
|
||||
const hasTc=Array.isArray(m.tool_calls)&&m.tool_calls.length>0;
|
||||
const hasTu=Array.isArray(m.content)&&m.content.some(p=>p&&p.type==='tool_use');
|
||||
if(msgContent(m)||m._statusCard||m.attachments?.length||(m.role==='assistant'&&(hasTc||hasTu||_messageHasReasoningPayload(m)))) visWithIdx.push({m,rawIdx});
|
||||
rawIdx++;
|
||||
}
|
||||
// Show a top affordance when earlier transcript content exists either in
|
||||
|
||||
Reference in New Issue
Block a user