From 59232fa168e3f8627ff3f49ce28af48ae7eb6e27 Mon Sep 17 00:00:00 2001 From: Matteo Nastasi Date: Sun, 13 Sep 2026 12:37:31 +0200 Subject: [PATCH] the chat redrew the box one line at a time Once the CHATT_MAXLINES ceiling was reached, every incoming message emptied the box and then filled it line by line, assigning innerHTML on each turn. Each += on innerHTML forces the browser to reserialise the content, reparse it and rebuild the subtree: 41 rebuilds of the DOM per message, with a cost that grows with the square of the number of lines. Now the shift happens on the array and the box is rewritten once. It came out of the load test: with 150 players chatting (15 messages a second broadcast to everybody) a real browser saturated twelve cores and died, while the daemon serving that traffic sat at 6% of one core. The bottleneck was the client, not the server. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_014M1jiEq9cHdE5SE5j6vFuE --- web/commons.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/web/commons.js b/web/commons.js index 762b600..106c9af 100644 --- a/web/commons.js +++ b/web/commons.js @@ -1108,13 +1108,16 @@ function chatt_sub(dt,data,str) // alert("ARRIVA NAME: "+ name + " STR:"+str); if (chatt_lines_n == CHATT_MAXLINES) { - $("txt").innerHTML = ""; + /* shift by one line and rewrite the box once. Before, every line was + appended to innerHTML on its own, and each += forces the browser to + reserialise and reparse the whole content: that was + CHATT_MAXLINES+1 rebuilds of the DOM for every message received. + In a crowded room the browser grinds to a halt. */ for (i = 0 ; i < (CHATT_MAXLINES - 1) ; i++) { chatt_lines[i] = chatt_lines[i+1]; - $("txt").innerHTML += chatt_lines[i]; } chatt_lines[i] = dt+name+": "+str+ "
"; - $("txt").innerHTML += chatt_lines[i]; + $("txt").innerHTML = chatt_lines.join(""); } else { chatt_lines[chatt_lines_n] = dt+name+": "+str+ "
"; -- 2.47.3