Fixes sluggish scrolling in Arena by virtualizing old messages, flattening 30k+ node Shiki codeblocks, and neutralizing CSS blurs and transitions.
// ==UserScript==
// @name Arena.ai | DOM Performance Optimizer
// @namespace https://greasyfork.org/en/users/1462137-piknockyou
// @version 2.4
// @author Piknockyou (vibe-coded)
// @license AGPL-3.0
// @description Fixes sluggish scrolling in Arena by virtualizing old messages, flattening 30k+ node Shiki codeblocks, and neutralizing CSS blurs and transitions.
// @match *://*.arena.ai/*
// @match *://*.canaryarena.ai/*
// @match *://chat.lmsys.org/*
// @icon https://arena.ai/favicon.ico
// @grant GM_addStyle
// @grant GM_getValue
// @grant GM_setValue
// @run-at document-start
// ==/UserScript==
(() => {
let hasStarted = false;
let pendingStart = false;
// ═══════════════════════════════════════════════════════════════════
// CONFIGURATION
// ═══════════════════════════════════════════════════════════════════
const DEFAULT_CONFIG = {
visibleMessages: 6, // Number of recent messages to keep fully rendered
flattenCodeblocks: true, // Strip <span> tags from old code blocks (massive React perf win)
killTransitions: true, // Disable expensive transition:all globally
killBlurs: true, // Disable backdrop-filter:blur (GPU win)
addContainment: true, // Add CSS containment for scroll isolation
autoClean: true, // Automatically prune on new messages
autoCleanDelay: 1000, // ms delay after DOM change before cleaning
showToolbar: true, // Show the bottom status toolbar
};
function getConfig() {
const stored = GM_getValue("arenaPerfConfigDOM", null);
if (stored) {
try {
return { ...DEFAULT_CONFIG, ...JSON.parse(stored) };
} catch (_e) {}
}
return { ...DEFAULT_CONFIG };
}
function saveConfig(cfg) {
GM_setValue("arenaPerfConfigDOM", JSON.stringify(cfg));
}
const config = getConfig();
// ⚡ INSTANT CSS INJECTION (Before body loads)
// This prevents the "flash" of transitions, blurs, and old messages.
try {
const SURGEON_ID = "arena-perf-surgeon";
const buildInitialCSS = () => {
const hideThreshold = config.visibleMessages + 1;
let css = `ol.flex-col-reverse > div:nth-child(n+${hideThreshold + 1}), ol.flex-col-reverse > li:nth-child(n+${hideThreshold + 1}) { display: none !important; }`;
if (config.killTransitions)
css += `*, *::before, *::after { transition: none !important; animation-duration: 0s !important; }`;
if (config.killBlurs)
css += `[class*="backdrop-blur"], [style*="backdrop-filter"] { backdrop-filter: none !important; -webkit-backdrop-filter: none !important; }`;
return css;
};
const style = document.createElement("style");
style.id = SURGEON_ID;
style.textContent = buildInitialCSS();
(document.head || document.documentElement).appendChild(style);
} catch (e) {
console.error("[ArenaPerf] Early CSS fail", e);
}
// ═══════════════════════════════════════════════════════════════════
// INTERNAL STATE
// ═══════════════════════════════════════════════════════════════════
let isPaused = false;
const stats = { hiddenMsgs: 0, totalMsgs: 0, nodesFlattened: 0 };
let observer = null;
let cleanTimeout = null;
let _settingsPopover = null;
// ═══════════════════════════════════════════════════════════════════
// MODULE A — CSS SURGEON
// ═══════════════════════════════════════════════════════════════════
const SURGEON_ID = "arena-perf-surgeon";
function buildSurgeonCSS() {
let css = `/* ── Arena Perf: Base ── */\n`;
// INSTANT VIRTUALIZATION: Hide messages via CSS before JS even runs
// We add +1 to account for the .h-0 spacer at index 0
const hideThreshold = config.visibleMessages + 1;
css += `
ol.flex-col-reverse > div:nth-child(n+${hideThreshold + 1}),
ol.flex-col-reverse > li:nth-child(n+${hideThreshold + 1}) {
display: none !important;
}
`;
if (config.killTransitions) {
css += `
/* Replace global transition:all with safe, cheap subset */
*, *::before, *::after {
transition-property: color, background-color, border-color, opacity, transform !important;
transition-duration: 150ms !important;
animation-duration: 0s !important;
}
/* Kill React max-height layout thrashing */
[class*="transition-[max-height]"] {
transition: none !important;
}
/* Kill scroll-behavior jank */[class*="overflow-"], [class*="scroller"], [data-radix-scroll-area-viewport] {
scroll-behavior: auto !important;
}
`;
}
if (config.killBlurs) {
css += `
/* Blurs destroy GPU composition on huge DOMs */[class*="backdrop-blur"], [style*="backdrop-filter"] {
backdrop-filter: none !important;
-webkit-backdrop-filter: none !important;
}
.bg-white\\/50 { background-color: rgba(255,255,255,0.95) !important; }
.bg-black\\/50 { background-color: rgba(0,0,0,0.95) !important; }
`;
}
if (config.addContainment) {
css += `
/* CSS Containment fences off layout calculations */
[data-radix-scroll-area-viewport] {
contain: layout paint;
}
ol.flex-col-reverse > div {
contain: content;
}
/* Isolate Markdown and Code elements */
pre, code,[class*="prose"] {
contain: content;
}
`;
}
return css;
}
function applySurgeryCSS() {
let el = document.getElementById(SURGEON_ID);
if (!el) {
el = document.createElement("style");
el.id = SURGEON_ID;
(document.head || document.documentElement).appendChild(el);
}
el.textContent = buildSurgeonCSS();
}
// ═══════════════════════════════════════════════════════════════════
// MODULE B — DOM VIRTUALIZER & FLATTENER
// ═══════════════════════════════════════════════════════════════════
// Arena uses `flex-col-reverse` for the chat container.
// This means DOM index [0] is the NEWEST message (visually at bottom),
// and DOM index[length - 1] is the OLDEST message (visually at top).
function getMessageContainer() {
return document.querySelector("ol.flex-col-reverse");
}
function getMessages(container) {
if (!container) return [];
return Array.from(container.children).filter((el) => {
const isMsg = el.tagName === "DIV" || el.tagName === "LI";
const isNotSpacer = !el.classList.contains("h-0");
return isMsg && isNotSpacer;
});
}
// Strips out Shiki <span> tags and leaves pure raw text.
// This stops React from reconciling 25,000+ nodes on every app state change.
function flattenShikiBlocks(msgNode) {
if (!config.flattenCodeblocks) return 0;
let flattened = 0;
const codes = msgNode.querySelectorAll(
'pre.shiki code:not([data-perf-flat="1"])',
);
codes.forEach((code) => {
if (code.children.length > 0) {
// Extract text line by line to preserve line breaks, preventing user messages from being mashed together
const lines = code.querySelectorAll(".line");
let rawText = "";
if (lines.length > 0) {
rawText = Array.from(lines)
.map((l) => l.textContent)
.join("\n");
} else {
rawText = code.textContent;
}
code.innerHTML = "";
code.textContent = rawText;
code.dataset.perfFlat = "1";
flattened++;
}
});
return flattened;
}
function cleanMessages() {
if (isPaused || !config.autoClean) return;
if (observer) observer.disconnect();
const container = getMessageContainer();
if (!container) return;
const msgs = getMessages(container);
stats.totalMsgs = msgs.length;
if (msgs.length <= config.visibleMessages) {
msgs.forEach((m) => {
m.style.display = "";
});
stats.hiddenMsgs = 0;
updateToolbar();
return;
}
let hidden = 0;
let newFlattened = 0;
// Because it's flex-col-reverse, indices 0 to (visibleMessages-1) are the newest.
// Everything after that is old and should be virtualized/hidden.
msgs.forEach((msg, index) => {
if (index < config.visibleMessages) {
// Keep visible
if (msg.style.display === "none") {
msg.style.display = "";
}
} else {
// Flatten and Hide
newFlattened += flattenShikiBlocks(msg);
if (msg.style.display !== "none") {
msg.style.display = "none";
}
hidden++;
}
});
stats.hiddenMsgs = hidden;
stats.nodesFlattened += newFlattened;
startObserver();
if (newFlattened > 0) {
console.log(
`[ArenaPerf] Flattened ${newFlattened} codeblocks in hidden messages.`,
);
}
updateToolbar();
}
function showAllMessages() {
const container = getMessageContainer();
if (!container) return;
getMessages(container).forEach((msg) => {
if (msg.style.display === "none") {
msg.style.display = "";
}
});
stats.hiddenMsgs = 0;
updateToolbar();
}
// ═══════════════════════════════════════════════════════════════════
// MODULE C — TOOLBAR UI
// ═══════════════════════════════════════════════════════════════════
const TOOLBAR_ID = "arena-perf-toolbar";
const POPOVER_ID = "arena-perf-settings";
let toolbarEl, statsEl, toggleBtn;
function createToolbar() {
if (!config.showToolbar || document.getElementById(TOOLBAR_ID)) return;
GM_addStyle(`
#${TOOLBAR_ID} {
position: fixed; bottom: 0; left: 50%; transform: translateX(-50%);
z-index: 2147483647; background: #09090b; color: #4ade80;
padding: 0 4px; border-radius: 6px 6px 0 0;
font: 11px/1.4 system-ui, sans-serif; display: flex; align-items: center; gap: 2px;
border: 1px solid #27272a; border-bottom: none; box-shadow: 0 -2px 10px rgba(0,0,0,0.5);
user-select: none;
}
#${TOOLBAR_ID} button {
all: unset; cursor: pointer; padding: 2px 8px; border-radius: 4px;
color: #e4e4e7; white-space: nowrap; transition: background 0.1s;
}
#${TOOLBAR_ID} button:hover { background: rgba(255,255,255,0.1); }
#${TOOLBAR_ID} .perf-stats { padding: 3px 6px; pointer-events: none; }
#${POPOVER_ID} {
position: fixed; bottom: 28px; left: 50%; transform: translateX(-50%);
z-index: 2147483647; background: #18181b; color: #e4e4e7;
border-radius: 10px; padding: 14px 18px; font: 13px/1.5 system-ui, sans-serif;
box-shadow: 0 -4px 24px rgba(0,0,0,0.6); border: 1px solid #27272a;
display: flex; flex-direction: column; gap: 8px; min-width: 260px;
}
#${POPOVER_ID} .perf-row {
display: flex; align-items: center; justify-content: space-between; gap: 12px;
padding: 6px 8px; border-radius: 6px; cursor: pointer;
}
#${POPOVER_ID} .perf-row:hover { background: rgba(255,255,255,0.05); }
#${POPOVER_ID} .perf-on { color: #4ade80; font-weight: bold; }
#${POPOVER_ID} .perf-off { color: #a1a1aa; font-weight: bold; }
#${POPOVER_ID} hr { border: 0; border-top: 1px solid #27272a; margin: 4px 0; }
`);
toolbarEl = document.createElement("div");
toolbarEl.id = TOOLBAR_ID;
toggleBtn = document.createElement("button");
toggleBtn.addEventListener("click", () => {
isPaused = !isPaused;
if (isPaused) showAllMessages();
else cleanMessages();
updateToolbar();
});
statsEl = document.createElement("span");
statsEl.className = "perf-stats";
const forceBtn = document.createElement("button");
forceBtn.textContent = "🧹";
forceBtn.title = "Force Clean Now";
forceBtn.addEventListener("click", () => {
isPaused = false;
cleanMessages();
});
const settingsBtn = document.createElement("button");
settingsBtn.textContent = "⚙️";
settingsBtn.addEventListener("click", toggleSettingsPopover);
toolbarEl.appendChild(toggleBtn);
toolbarEl.appendChild(statsEl);
toolbarEl.appendChild(forceBtn);
toolbarEl.appendChild(settingsBtn);
document.body.appendChild(toolbarEl);
updateToolbar();
// Start watchdog to prevent React from permanently removing the toolbar
setInterval(() => {
if (toolbarEl && !document.body.contains(toolbarEl)) {
console.log("[ArenaPerf] Watchdog: Re-attaching toolbar");
document.body.appendChild(toolbarEl);
}
}, 2000);
}
function updateToolbar() {
if (!statsEl) return;
toggleBtn.textContent = isPaused ? "👁️ All" : "🔒 Hide";
toggleBtn.style.color = isPaused ? "#fcd34d" : "#e4e4e7";
const statText = isPaused
? `${stats.totalMsgs} msgs · paused`
: `${stats.totalMsgs - stats.hiddenMsgs}/${stats.totalMsgs} msgs`;
statsEl.textContent = statText;
statsEl.style.color = isPaused
? "#fcd34d"
: stats.hiddenMsgs > 0
? "#4ade80"
: "#a1a1aa";
}
function toggleSettingsPopover() {
if (_settingsPopover) {
_settingsPopover.remove();
_settingsPopover = null;
return;
}
const panel = document.createElement("div");
panel.id = POPOVER_ID;
function addToggle(icon, label, getValue, onToggle) {
const row = document.createElement("div");
row.className = "perf-row";
const render = () => {
const on = getValue();
row.innerHTML = `<span>${icon} ${label}</span><span class="${on ? "perf-on" : "perf-off"}">${on ? "ON" : "OFF"}</span>`;
};
render();
row.addEventListener("click", () => {
onToggle();
render();
saveConfig(config);
});
panel.appendChild(row);
}
const head = document.createElement("div");
head.style.cssText =
"font-weight:bold; font-size:14px; margin-bottom:4px; text-align:center;";
head.textContent = "DOM Optimizer Settings";
panel.appendChild(head);
addToggle(
"⚡",
"Kill Transitions",
() => config.killTransitions,
() => {
config.killTransitions = !config.killTransitions;
applySurgeryCSS();
},
);
addToggle(
"🌫️",
"Kill GPU Blurs",
() => config.killBlurs,
() => {
config.killBlurs = !config.killBlurs;
applySurgeryCSS();
},
);
addToggle(
"🔥",
"Flatten Shiki Spans",
() => config.flattenCodeblocks,
() => {
config.flattenCodeblocks = !config.flattenCodeblocks;
if (config.flattenCodeblocks) cleanMessages();
},
);
addToggle(
"📦",
"CSS Containment",
() => config.addContainment,
() => {
config.addContainment = !config.addContainment;
applySurgeryCSS();
},
);
panel.appendChild(document.createElement("hr"));
const numRow = document.createElement("div");
numRow.className = "perf-row";
numRow.innerHTML = `<span>📝 Visible Messages</span><span style="color:#60a5fa;font-weight:bold">${config.visibleMessages}</span>`;
numRow.addEventListener("click", () => {
const val = prompt(
"Number of recent messages to keep visible?",
config.visibleMessages,
);
const num = parseInt(val, 10);
if (num && num > 0) {
config.visibleMessages = num;
saveConfig(config);
cleanMessages();
panel.remove();
_settingsPopover = null;
}
});
panel.appendChild(numRow);
document.body.appendChild(panel);
_settingsPopover = panel;
// Auto-close on click outside
setTimeout(() => {
const closeHandler = (e) => {
if (!panel.contains(e.target) && !toolbarEl.contains(e.target)) {
panel.remove();
_settingsPopover = null;
document.removeEventListener("mousedown", closeHandler);
}
};
document.addEventListener("mousedown", closeHandler);
}, 0);
}
// ═══════════════════════════════════════════════════════════════════
// MODULE D — OBSERVER & ORCHESTRATOR
// ═══════════════════════════════════════════════════════════════════
function scheduleClean() {
if (cleanTimeout) clearTimeout(cleanTimeout);
cleanTimeout = setTimeout(cleanMessages, config.autoCleanDelay);
}
function startObserver() {
if (observer) observer.disconnect();
observer = new MutationObserver((mutations) => {
let shouldClean = false;
for (const m of mutations) {
// If a new message is added to the list
if (m.type === "childList" && m.addedNodes.length > 0) {
shouldClean = true;
break;
}
}
if (shouldClean) scheduleClean();
});
// Observe the body to handle SPA navigations where the ol container swaps
observer.observe(document.body, { childList: true, subtree: true });
}
function initializeUI() {
if (document.visibilityState !== "visible") {
pendingStart = true;
console.log("[ArenaPerf] Deferring init until tab is visible");
return;
}
if (hasStarted) return;
hasStarted = true;
console.log("[ArenaPerf] Booting DOM Virtualizer & Flattener...");
applySurgeryCSS();
if (config.showToolbar) createToolbar();
startObserver();
// Initial passes
setTimeout(cleanMessages, 1000);
setTimeout(cleanMessages, 3000);
}
function scheduleInit() {
if (document.visibilityState !== "visible") {
pendingStart = true;
return;
}
if (window.requestIdleCallback) {
const idleId = window.requestIdleCallback(initializeUI, {
timeout: 1000,
});
setTimeout(() => {
if (!hasStarted) {
window.cancelIdleCallback(idleId);
initializeUI();
}
}, 1500);
} else {
setTimeout(initializeUI, 100);
}
}
function waitForReady() {
const READY_SELECTOR = "form textarea";
if (document.querySelector(READY_SELECTOR)) {
scheduleInit();
return;
}
const readyObserver = new MutationObserver(() => {
if (document.querySelector(READY_SELECTOR)) {
readyObserver.disconnect();
setTimeout(scheduleInit, 200);
}
});
readyObserver.observe(document.body, { childList: true, subtree: true });
}
document.addEventListener("visibilitychange", () => {
if (document.visibilityState !== "visible") return;
if (pendingStart && !hasStarted) {
pendingStart = false;
setTimeout(initializeUI, 250);
}
});
setTimeout(() => {
if (document.visibilityState !== "visible") {
pendingStart = true;
return;
}
if (!hasStarted && document.querySelector("form textarea")) {
console.warn("[ArenaPerf] Emergency init after 5s");
initializeUI();
}
}, 5000);
// Ultra-fast Body Detection (Faster than DOMContentLoaded)
if (document.body) {
waitForReady();
} else {
const bodyObserver = new MutationObserver(() => {
if (document.body) {
bodyObserver.disconnect();
waitForReady();
}
});
bodyObserver.observe(document.documentElement, { childList: true });
}
})();