Skip to content

/twins/[slug]?ortho freezes the main thread for 4.7s (17.8s total blocking) — the E2E click timeout is real #717

Description

@TortoiseWolfe

tests/e2e/twins.spec.ts:98 ("Top-down compare mode (#233)") has failed on main for at
least eight consecutive E2E runs. The test is valid and the UI is not broken — the
page is genuinely unresponsive, and the test is correctly refusing to click a frozen button.

Measured

/twins/chatt/?ortho on a machine with real GPU WebGL (CI runs software rendering, so
CI is worse):

long tasks (>50 ms)  : 36
longest single task  : 4,740 ms     <- main thread frozen ~4.7 s
total blocking time  : 17,783 ms    <- Google's "good" threshold is 200 ms

Where the time goes — CDP CPU profile, self time

This replaces the guessed candidate list that was in this issue originally. The profile
names the functions:

_buildNodes           364 ms + 192 ms   binned-SAH BVH node builder (src/lib/cod/bvh.js)
_nodeBoundsFromRange   97 ms +  50 ms   same
StaticWorld.build      74 ms
                      ----------------
                      ~780 ms of BVH construction

texSubImage2D         250 ms            drape texture upload
getProgramInfoLog     105 ms +  61 ms   forces a SYNCHRONOUS shader-link wait

Roughly 10 s of the sampled window is native (program) — GPU and browser work not
attributable to a JS frame, which is expected for a WebGL-heavy route.

The single largest item is work this route cannot use

tryBuildWalk() in src/twin/TwinCanvas.client.tsx gates only on
buildings && terrain && groundAt. It has no mode check — the "mode" occurrences inside
it are comments. It is invoked from handleBuildingsMesh, handleTerrainMesh and
handleGroundReady, so the full collision BVH is built on every twin route.

?ortho maps to rig mode orbit (mode === 'ortho' ? 'orbit' : mode), and Rig.collide
is only ever called inside _walk() (Rig.ts:573). Orbit, ortho, tour and follow never
touch the collision world.

Tracked separately as its own fix, since it is the actionable one.

Why it presents as a click timeout

- element is visible, enabled and stable
- scrolling into view if needed / done scrolling
- performing click action
TimeoutError: locator.click: Timeout 15000ms exceeded

The button is found, actionable, and clicked. The input cannot be processed because the main
thread is blocked. Verified by hand with real WebGL on a warm page: nothing overlays the
button, aria-expanded flips to true, and Top-down appears. The mechanism is fine.

This is a user-facing defect

A visitor to ?ortho cannot interact with the HUD for ~5 seconds, and the tab is janky for
another twelve. The test is the messenger.

Do not fix this by raising actionTimeout. That makes the suite green while leaving the
page frozen, and destroys the signal. A previous attempt added test.slow() (see the spec's
own comment), which raised the test budget and not the action budget — which is why it
did not help.

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions