Files
ai-app/app
irisandClaude Opus 5 f9432b69cc Keep every row laid out, but only draw the ones near the screen
Iris's Pixel 9 Pro XL said which half was costing, and it was not the
half either of us was looking at. With 138 rows loaded: layout 0.0ms at
the median, GPU 1.9ms, and **draw 13.6ms** against a 120Hz budget of
8.3ms. Nothing was being re-measured and the phone's rasteriser was
idle; the UI thread was recording draw commands for a transcript that
was almost entirely off screen.

Retaining rows was right and stays. What does not follow the same rule
is drawing: the draw pass walks the whole tree, so a list that keeps
every row alive records every row every frame, and that cost grows with
each page of history -- which is exactly what "worse afterwards" was.
Composition and measurement are what must not be thrown away, because
they are what has to be rebuilt from nothing when the reader comes back.
A display list is rebuilt from a layout that is still there.

So each row skips its own draw when it is off screen, by more than a
screen's margin either side. The check reads the scroll position from
the draw phase, so moving the list invalidates drawing and nothing else,
and it is a lookup rather than a sum -- the running totals are rebuilt at
most once a frame and only after something has actually changed height,
since adding them up per row per lookup would have made the fix
quadratic in the thing it was fixing.

Also reports the three frame phases that were missing, which is why the
phases on that reading did not add up to the total: the time a frame
spent waiting for the UI thread to be free, handling input, and running
animations. About 15ms of the 30.6 was in that gap and unattributed.

On the emulator, same transcript, before and after: draw p50 3.9ms ->
2.5ms, p90 7.3ms -> 4.2ms, p99 48.6ms -> 5.2ms. The saving there is
small because only 60 rows were loaded; it is proportional to how much
is off screen, and on the phone that was 95,000px of content against a
1,474px viewport.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-31 02:20:03 -04:00
..