mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-10-09 08:59:40 +02:00
perf(resize): a window resize fits each grid tile once, not twice
A window resize reached every grid tile twice: the grid's own
ResizeObserver refits them (tile-grid.js _scheduleTileGridRefit, 150 ms
trailing), then the main terminal's trailing resize timer (terminal-ui.js
throttledResize, 300 ms) ran _forEachTile(fit) over them again. The second
pass re-measured six panes and sent nothing (_lastSentDims dedupes the PTY
side). The timer now refits the split's Pane B only ({ grid: false }); grid
tiles exist only while the grid owns the terminal, and then its observer
already covers them.
Measured (6 tiles, 20-step window resize and back, headless, tileperf):
fit() 12 -> 6 per resize burst; PTY resizes 6 -> 6; browser layouts
unchanged within noise (85/75 -> 92/71), so this removes wasted calls only.
Live, this code (6 tiles, tileperf): a 20-step window resize, and the resize
back, each ran fit() 6 times and sent 6 PTY resizes (12 and 6 before).
Test: the timer's one _forEachTile call passes { grid: false } (it lives
inside initTerminal, so read from source like the #464 geometry tests);
mutation-checked.
Scope: PR 2. The line is in terminal-ui.js (a PR 1 seam), but on PR 1 alone
_forEachTile reaches only the split's Pane B: the double refit needs the grid.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -29,6 +29,8 @@
|
||||
* tile-grid.js in one `vm` context, with the shared fake DOM and fake
|
||||
* TerminalTile (test/mocks/tile-grid-vm.ts). Port: N/A.
|
||||
*/
|
||||
import { readFileSync } from 'node:fs';
|
||||
import { resolve } from 'node:path';
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
import {
|
||||
FakeTile,
|
||||
@@ -357,6 +359,22 @@ describe('panes and fonts while the grid is open', () => {
|
||||
expect(pane.sessionId).toBe('s-a');
|
||||
});
|
||||
|
||||
it("the main terminal's window-resize timer leaves grid tiles to the grid's own observer", () => {
|
||||
// A window resize fires both: the grid's ResizeObserver refits every tile
|
||||
// (tile-grid.js _scheduleTileGridRefit) and the main terminal's trailing
|
||||
// timer used to refit them again, twelve fit() calls for six tiles and
|
||||
// nothing more sent (measured). The timer lives inside initTerminal(), so
|
||||
// this reads its source; the split's Pane B is still refitted there.
|
||||
const src = readFileSync(resolve(import.meta.dirname, '../src/web/public/terminal-ui.js'), 'utf8');
|
||||
const start = src.indexOf('const throttledResize = () => {');
|
||||
const end = src.indexOf("window.addEventListener('resize', throttledResize)", start);
|
||||
expect(start).toBeGreaterThan(-1);
|
||||
expect(end).toBeGreaterThan(start);
|
||||
const calls = src.slice(start, end).match(/this\._forEachTile\?\.\([^;]*;/g) ?? [];
|
||||
expect(calls).toHaveLength(1);
|
||||
expect(calls[0]).toContain('{ grid: false }');
|
||||
});
|
||||
|
||||
it('_forEachTile reaches every grid tile; { grid: false } skips them', () => {
|
||||
const app = appWithGrid(true);
|
||||
const seen: string[] = [];
|
||||
|
||||
Reference in New Issue
Block a user