Skip to content

Releases: HanzheLee/longchat-perf

v0.3.1 — Fix wide-table clipping with off-screen rendering skip (#1)

Choose a tag to compare

@HanzheLee HanzheLee released this 21 Aug 22:05

Highlights

Fixed: wide tables clipped when off-screen rendering skip is on (#1)

Reported by @alittleswarm — with the core rendering-skip patch enabled, wide
tables rendered truncated (a whole block missing on the right side).

Root cause (confirmed via a minimal headless repro, Chrome 151):

  • content-visibility: auto implies paint containment: descendant
    painting is clipped to the message column's border box.
  • ChatGPT's wide-table container is a negative-margin full-bleed layout
    that deliberately overflows the message column into the side gutters to
    gain horizontal room (that's why wide tables can be wider than the text
    column).
  • Combined, everything the table draws beyond the message column gets
    clipped. Layout stays correct (getBoundingClientRect is identical with
    the patch on/off) — only painting is cut, which is why it looked like
    "missing render" rather than a broken layout.
Repro scenario Table painted width
Patch off 1050px (full)
Patch on (v0.3.0) 764px (≈ message column, right side blank)
Patch on (v0.3.1) 1050px (full)

Fix: patch-1 selectors now carry :not(:has(table)) — messages that
contain a table never receive content-visibility. Tables are a tiny share
of messages in long conversations, so the perf cost is negligible.

Notes:

  • Pure CSS; React re-renders stay correct, and nothing depends on ChatGPT's
    build-specific class names.
  • Patch 1 now requires :has() support — Chrome/Edge 105+, Firefox 121+,
    Safari 15.4+
    . On older browsers the rule is dropped entirely and patch 1
    simply doesn't apply (safe degradation; all other patches keep working).
  • Workaround before upgrading: turn off the "off-screen rendering skip"
    toggle in the popup and reload the page.

中文摘要

**v0.3.1 变更要点:**修复 #1
——开启「屏外渲染跳过」后宽表格右侧被截断的问题。

根因:content-visibility: auto 隐含 paint containment,后代绘制被裁剪到
消息列边框盒;而 ChatGPT 的宽表格容器是负 margin 全出血布局,故意溢出消息
列借用两侧留白 —— 溢出部分被整体裁掉(布局测量不变,纯绘制裁剪)。
已在最小化复现环境中确认并验证修复(表格绘制宽度 764px → 1050px 完整)。

修复方式:含表格的消息自动退出屏外渲染跳过(:not(:has(table))),
纯 CSS、不依赖站点类名;表格消息占比极小,性能影响可忽略。
补丁 1 兼容性下限随之调整为 Chrome/Edge 105+、Firefox 121+、Safari 15.4+
(更旧浏览器自动停用该补丁,其余补丁不受影响)。

升级前临时规避:弹窗中关闭「屏外渲染跳过」开关并刷新页面。

Upgrade

The extension is still load-unpacked:

  1. Download longchat-perf-v0.3.1.zip below and unzip it over your
    existing longchat-perf/ folder (replace files when prompted);
  2. Open chrome://extensions and click the reload (↻) button on the
    LongChat Perf card; refresh any open ChatGPT tabs.

Your settings are kept (stored in chrome.storage.sync).

v0.3.0 — CodeMirror batch mounting (conversation-switch freezes -87%)

Choose a tag to compare

@HanzheLee HanzheLee released this 17 Aug 15:51

Highlights

Patch 5 — CodeMirror batch mounting

The heaviest DOM in long ChatGPT conversations is code blocks (CodeMirror 6
editors). Opening or switching a conversation mounts dozens to hundreds of
editor instances at once, each triggering a full-page style recalculation —
the direct cause of "switching chats freezes the tab for tens of seconds".

Patch 5 intercepts the insertion of not-yet-initialized CodeMirror roots
(structure-fingerprinted), holds them detached — detached subtrees do not
invalidate page styles — and mounts the whole batch in a single task. N full-page
style recalculations become 1.

  • Runs in the page's main world via content_scripts[].world: "MAIN"
    (Chrome 111+; on older browsers it simply does not run, other patches
    are unaffected)
  • Fails safe: anything that doesn't match the fingerprint passes through
    natively; if a ChatGPT redesign breaks the fingerprint, the patch degrades
    to pass-through and the popup shows a "patch may be stale" warning
  • Yields automatically if a Tampermonkey userscript variant
    (__CHATGPT_CM_PERF_FIX__) is already installed

Long-task monitor (popup)

A built-in local monitor tracks all >50 ms main-thread tasks (cumulative /
worst / per-batch). Toggle the patch off and on, reload, switch the same
conversations — the difference is the blocking time the patch saves. In-memory
only, never transmitted.

DevTools trace analyzer

tools/trace-analyze.js streams DevTools enhanced traces (.json/.json.gz,
tested at 750 MB) and reports main-thread busy time, long tasks with inner
phase attribution, and monitor overhead. Batch mounts are also marked with
performance.mark('lcp-cm-batch'), visible in the DevTools Timings track.

Real-world A/B (Chrome, ~624 editors across 9 conversation switches)

Metric Patch on Patch off Improvement
Cumulative long tasks 20.0s 41.4s -52%
Worst single freeze 1.1s 8.5s -87%
Interception rate 624/624 (9 batches) — 100%

Also CI now runs the 49-assertion jsdom smoke suite on every push (Node 20/22).

中文摘要

v0.3.0 变更要点:

  1. 新增补丁 5「代码块批量挂载」:拦截 CodeMirror 编辑器的挂载并合并为单批,
    将 N 次整页样式重算摊销为 1 次,专治「打开/切换长会话卡死几十秒」;
  2. 弹窗内置本地长任务监视器:开关补丁前后对比即可自行验证效果;
  3. 新增 DevTools trace 流式分析工具与 GitHub Actions CI。
指标 开启 关闭 改善
累计长任务 20.0s 41.4s -52%
最长单次冻结 1.1s 8.5s -87%
拦截率 624/624(9 批) — 100%

Upgrade from v0.1.0

The extension is still load-unpacked, so upgrading is:

  1. Download longchat-perf-v0.3.0.zip below and unzip it over your
    existing longchat-perf/ folder (replace files when prompted);
  2. Open chrome://extensions and click the reload (↻) button on the
    LongChat Perf card; refresh any open ChatGPT tabs.

Your settings are kept (stored in chrome.storage.sync). The new patch 5
toggle is on by default and needs Chrome 111+.

v0.1.0

Choose a tag to compare

@HanzheLee HanzheLee released this 16 Aug 09:33

LongChat Perf v0.1.0

A tiny, local-only rendering patch for keeping long ChatGPT conversations responsive.

No network requests.  No analytics.  No message deletion.

Install

  1. Download longchat-perf-v0.1.0.zip
  2. Unzip → open chrome://extensions (or edge://extensions)
  3. Enable Developer mode → Load unpacked → select the unzipped longchat-perf folder

What's inside

  • Off-screen rendering skip (content-visibility: auto)
  • Backdrop-filter disable (optional aggressive patch)
  • Progressive old-message folding — scroll-driven, CSS-based, reversible, never auto-folds
  • Streaming-phase throttle (pauses message-area animations while answers stream)
  • Popup controls for every patch + fold-now / expand-all buttons
  • npm test — jsdom-based smoke test, 24 assertions

Notes

  • Local-only: no network requests, no analytics, no message deletion, storage permission only
  • Unofficial — not affiliated with or endorsed by OpenAI
  • Targets ChatGPT's stable DOM attributes (div[data-message-author-role][data-message-id]);
    compatibility may need revalidation if ChatGPT changes its DOM structure