diff --git a/web/MinesweeperPanel.tsx b/web/MinesweeperPanel.tsx index 014c0c4..17bed45 100644 --- a/web/MinesweeperPanel.tsx +++ b/web/MinesweeperPanel.tsx @@ -82,6 +82,19 @@ export const MinesweeperPanel = () => { const [frame, setFrame] = useState<{ width: number; height: number } | null>(null); const [box, setBox] = useState<{ width: number; height: number; dpr: number; zoom: number } | null>(null); const [status, setStatus] = useState(null); + /* + TEMPORARY INSTRUMENTATION — press-to-paint, measured where it is actually felt. + + The same figure taken at x11vnc's own socket is ~50ms (median 47ms over 8 synthetic presses, and 51ms + with the X DAMAGE extension enabled, so `-noxdamage` is not costing anything). What that number cannot + include is the two relay hops and the network, and those are the only places the rest of the lag can + be. This is the end-to-end figure, so the two can be subtracted. + + Cleared on the frame that follows a press, so it times the first paint after a click rather than every + repaint. Delete this and its row below once the question is settled. + */ + const pressAtRef = useRef(null); + const [lagMs, setLagMs] = useState(null); const [error, setError] = useState(null); const [connected, setConnected] = useState(false); const [busy, setBusy] = useState(false); @@ -200,6 +213,10 @@ export const MinesweeperPanel = () => { }, onFrame: (image, x, y) => { canvasRef.current?.getContext('2d')?.putImageData(image, x, y); + if (pressAtRef.current !== null) { + setLagMs(Math.round(performance.now() - pressAtRef.current)); + pressAtRef.current = null; + } }, onCopyRect: (from, to) => { // Same canvas as source and destination, which is what CopyRect is: the 2D context takes a @@ -301,7 +318,10 @@ export const MinesweeperPanel = () => { const rfb = rfbRef.current; if (!rfb) return; ev.preventDefault(); - if (kind === 'down') ev.currentTarget.focus(); + if (kind === 'down') { + ev.currentTarget.focus(); + pressAtRef.current = performance.now(); + } if (kind !== 'move') { const bit = BUTTON_MASK[ev.button] ?? 0; @@ -351,6 +371,10 @@ export const MinesweeperPanel = () => { game or a repair for when it stops behaving, and a footer is where neither gets read. */}
{connected ? 'connected' : 'connecting…'} + {/* Temporary — see `pressAtRef`. ~50ms of this is the game and the capture; the rest is the trip. */} + + lag {lagMs === null ? '—' : `${lagMs}ms`} + {/* Focus decides where keys go, and a canvas gives no hint that it can hold any. */} click the board to send it keys