mirror of
https://github.com/Studio-Saelix/sencho.git
synced 2026-08-13 12:17:34 +00:00
fix(logs): cap DOM rendering to 300 rows to prevent OOM crash
Playwright investigation revealed the Logs view (GlobalObservabilityView) rendered 1,859+ log entries as real DOM nodes (9,616 total DOM nodes) with no virtualization. Combined with a 5-second polling cycle replacing all React elements each time and smooth-scroll animations stacking on every update, the renderer process grew rapidly on a host running at 97% RAM usage, crashing the browser tab with Out of Memory within minutes. Fixes: - Cap rendered DOM rows to MAX_DISPLAY_ROWS (300) via .slice(-300) so the browser only ever holds ~1,500 log-related DOM nodes regardless of how many entries are in state - Add a truncation notice when log count exceeds the display cap - Reduce SSE-mode in-memory log cap from 10,000 to MAX_LOG_ENTRIES (2,000) - Switch auto-scroll from behavior:'smooth' to behavior:'instant' to stop stacking layout animations on every 5-second poll - Reduce /api/logs/global response limit from 2,000 to 500 lines since the client renders at most 300 rows, making the extra payload wasteful
This commit is contained in:
@@ -1072,9 +1072,11 @@ app.get('/api/logs/global', async (req: Request, res: Response) => {
|
||||
}
|
||||
}));
|
||||
|
||||
// Sort globally by timestamp ascending (newest bottom) and limit to 2000 lines
|
||||
// Sort globally by timestamp ascending (newest bottom).
|
||||
// Limit to 500 lines — the client renders at most 300 rows at once, so
|
||||
// sending 2000 lines was wasting bandwidth and inflating JSON parse time.
|
||||
allLogs.sort((a, b) => a.timestampMs - b.timestampMs);
|
||||
res.json(allLogs.slice(-2000));
|
||||
res.json(allLogs.slice(-500));
|
||||
} catch (error) {
|
||||
res.status(500).json({ error: 'Failed to fetch global logs' });
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user