From f2abe50b7c4abf7b0f90252eba8a790426e858a8 Mon Sep 17 00:00:00 2001 From: sintez Date: Tue, 23 Jun 2026 02:13:34 +0300 Subject: [PATCH] perf: skip gateway poll when hidden/streaming, re-init smd parser before innerHTML fallback --- static/messages.js | 7 +++++++ static/sessions.js | 18 +++++++++++++++++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/static/messages.js b/static/messages.js index cf15b25b..12b1ba88 100644 --- a/static/messages.js +++ b/static/messages.js @@ -3352,6 +3352,13 @@ function attachLiveStream(activeSid, streamId, uploaded=[], options={}){ : _stripXmlToolCalls(assistantText.slice(segmentStart)); if(_smdParser){ _smdWrite(displayText); + } else if(window.smd){ + // Parser was nulled out (e.g. by a prior segment end) but smd is + // available — recreate it on the existing element. Uses the non-fade + // renderer to match standard rendering, avoiding O(n²) innerHTML + // churn on long responses (#4704). + _smdNewParser(assistantBody, false); + if(_smdParser) _smdWrite(displayText); } else if(renderMd){ assistantBody.innerHTML=renderMd(displayText); } else { diff --git a/static/sessions.js b/static/sessions.js index 062fd639..1867768e 100644 --- a/static/sessions.js +++ b/static/sessions.js @@ -4101,7 +4101,23 @@ if(typeof window!=='undefined') window.refreshSessionList = refreshSessionList; function startGatewayPollFallback(ms){ const intervalMs = Math.max(5000, Number(ms) || _gatewayFallbackPollMs); if(_gatewayPollTimer) clearInterval(_gatewayPollTimer); - _gatewayPollTimer = setInterval(() => { renderSessionList({deferWhileInteracting:true}); }, intervalMs); + _gatewayPollTimer = setInterval(() => { + // Skip poll when tab is hidden or a stream is active — saves CPU + // and avoids redundant DOM renders during active streaming (#4704). + if(typeof document !== 'undefined' && document.hidden) return; + if(typeof S !== 'undefined' && (S.busy || S.activeStreamId)) return; + renderSessionList({deferWhileInteracting:true}); + }, intervalMs); + // Visibility catch-up: refresh immediately when tab re-gains focus, + // so no gateway updates are dropped during hidden-skip periods. + if(typeof document !== 'undefined' && !document._hermesGatewayPollVisibilityHook){ + document.addEventListener('visibilitychange', () => { + if(!document.hidden && typeof renderSessionList === 'function'){ + void renderSessionList({deferWhileInteracting:false}); + } + }); + document._hermesGatewayPollVisibilityHook = true; + } } function stopGatewayPollFallback(){