Skip to content
dsh.fish
Bundle

dsh-chat-offscreen

Keep long DSH chat sessions responsive: skip layout/paint for off-screen transcript rows (content-visibility).

Source
publieople
License
MIT
Updated
Updated 18 hours ago

Readme

# dsh-chat-offscreen

Keep long DeepSeek Harness (DSH) Web chat sessions responsive.

## The problem

The DSH chat transcript is **not virtualized** upstream: every loaded history
page stays in the DOM. Backwards paging pulls 50 messages per `loadOlder()`
page, and the turn rail's jump loader pulls 200-message pages until the window
covers the target — with no eviction. On a long session, dragging the
transcript width handle, the sidebar divider, or simply scrolling forces
layout + paint across thousands of nodes, which makes the UI stutter.

## What this plugin does

It is a tiny client-side plugin that installs one stylesheet:

```css
[data-chat-flow-kind="assistant-step"]:not(:has(.md-table-wide)),
[data-chat-flow-kind="tool-call"]:not(:has(.md-table-wide)) {
  content-visibility: auto;
  contain-intrinsic-size: auto 120px;
}
[data-chat-flow-kind="assistant-step"]:has(.md-table-wide),
[data-chat-flow-kind="tool-call"]:has(.md-table-wide) {
  content-visibility: visible !important;
  contain: none !important;
}
```

`content-visibility: auto` lets the browser skip layout and paint for
off-screen assistant steps and tool calls — a cheap approximation of
virtualization — while `contain-intrinsic-size: auto 120px` keeps the scroll
range stable and remembers a row's measured height once seen. Rows containing a
wide markdown table opt out so their breakout width is never mis-estimated.

This is a rendering-layer workaround, not a data change: no messages, session
events, or host state are touched. It composes with the retired
`@linxin666/dsh-perf` P0 rule of the same shape.

## Install

```sh
dsh plugin --profile web add github:publieople/dsh-chat-offscreen
```

Then restart the web profile (`dsh web ...`) and hard-refresh the page
(`Ctrl+Shift+R`). The `lib/` build is committed, so no package build script
runs and no `allowBuilds` entry is required.

The bundle patch inserts the plugin row automatically. If you install by hand:

```sh
cd "$DSH_HOME/profiles/web"
pnpm add github:publieople/dsh-chat-offscreen
```

then add `dsh-chat-offscreen` to `dsh.profile.bundles` in that profile's
`package.json` and restart.

## Verify

Open a long session and drag the transcript width handle / sidebar divider, or
scroll fast. In DevTools → Elements, an off-screen assistant step should carry
`content-visibility: auto`.

## Disable / uninstall

```sh
dsh plugin --profile web remove dsh-chat-offscreen
```

then restart. Removing the plugin removes the stylesheet; nothing is persisted.

## Compatibility

- Client platform: `web`. Host half is intentionally empty.
- Depends only on the browser `content-visibility` feature (Chrome/Edge 85+,
  Firefox 125+, Safari 18+). On older engines the rules are inert and the UI
  simply stays as before.
- Built against DSH `0.1.5-rc.1`; the plugin uses no DSH runtime imports.

## Development

```sh
npm install
npm run typecheck
npm run build     # tsdown -> lib/index.js (ESM) + lib/client.js (ModuleLoader)
npm test          # drives the built client bundle against a fake DOM
```

`lib/` is committed on purpose so Git installs need no build step. If you change
`src/`, re-run `npm run build` and commit the result.

## If upstream virtualizes the chat

When the DSH chat surface gains real virtualization, delete this plugin row.
The upstream trajectory view (`ui-trajectory`) is already virtualized; the chat
surface is not.

Install

dsh plugin --profile web add github:publieople/dsh-chat-offscreen

Profile: web

  • This package builds from source on install. pnpm will ask you to allow its build script — that is permission to run the package’s code on your machine, outside the agent sandbox. Only allow sources you trust.
  • This source has no pinned commit, so a later push upstream changes what installs. Prefer pinning a commit.
Source