From c35e8a9b44094fe129b8fb31153ea2b0b11e22ce Mon Sep 17 00:00:00 2001 From: oyi77 Date: Tue, 14 Jul 2026 04:16:21 +0700 Subject: [PATCH] fix(perf): prevent memory leak and TextEncoder allocation on hot path - Add performance.clearMarks/clearMeasures before creating new marks to prevent timeline accumulation in long-lived processes. - Replace new TextEncoder().encode(str).length with Buffer.byteLength to avoid allocating a full Uint8Array just to measure byte length. --- open-sse/handlers/chatCore/streamingPipeline.ts | 3 +++ open-sse/utils/stream.ts | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/open-sse/handlers/chatCore/streamingPipeline.ts b/open-sse/handlers/chatCore/streamingPipeline.ts index 429b3d79de..2a6a7c00bb 100644 --- a/open-sse/handlers/chatCore/streamingPipeline.ts +++ b/open-sse/handlers/chatCore/streamingPipeline.ts @@ -72,6 +72,9 @@ export function assembleStreamingPipeline( }, deps: StreamingPipelineDeps = DEFAULT_DEPS ) { + performance.clearMarks(PIPELINE_START); + performance.clearMarks(PIPELINE_END); + performance.clearMeasures(PIPELINE_MEASURE); performance.mark(PIPELINE_START); // ── Phase 9.3: Progress tracking (opt-in) ── const progressEnabled = deps.wantsProgress(args.clientRawRequestHeaders); diff --git a/open-sse/utils/stream.ts b/open-sse/utils/stream.ts index e145ab4290..23e6b32cb2 100644 --- a/open-sse/utils/stream.ts +++ b/open-sse/utils/stream.ts @@ -644,7 +644,7 @@ export function createSSEStream(options: StreamOptions = {}) { // tools can query performance.getEntriesByType("mark") filtered by name. let bodySize = 0; try { - bodySize = body ? new TextEncoder().encode(JSON.stringify(body)).length : 0; + bodySize = body ? Buffer.byteLength(JSON.stringify(body), "utf8") : 0; } catch { /* body may not be JSON-serialisable (e.g. FormData, Blob) — metric stays 0 */ }