Async inserts should occupy positions that do not interrupt reading
Aliases: in-article insert · append below fold · reading-position stable · mid-content injection
What it is
An asynchronously arriving module still has to pick a slot. If it injects into the passage currently being read, the reader must re-find the line. If it lands below the viewport, in a sidebar, or outside the reading surface, the current viewport can stay still. Prefer insert positions that do not interrupt reading constrains the insertion point relative to the reading cursor. It is not “late content always pushes nodes,” and it is not “freeze hittable clusters.” The cost here is losing one’s place in the text.
Why it happens
Reading holds an attention trace in the viewport: current line, current paragraph, scroll offset. Injecting an in-flow block into the middle of that trace adds height above the fixation, every later line translates, and the reader must relocate. When the insertion point is below the current viewport, painted line boxes keep their coordinates; the new block appears only on further scroll. When it sits in a sidebar or a fixed rail, the main column’s line boxes are untouched.
So the same async arrival is an interruption or an append depending on slot. The usual product failure is dropping recs, related-reading, or a subscribe bar between body paragraphs or mid-screen because that inventory pays more. The engineering default is: the reading surface appends, it does not mid-insert; mid-insert happens only when the user asked (expand, load-more that keeps original line positions).
Where it stops holding
In chats, logs, and collaborative cursors the “current reading position” is the bottom; appending there is expected, not an interruption. Inserting history above can shove the already-read position, and needs scroll anchoring. Maps and canvases have no document lines, so this reading-cursor model does not apply. Editors with uniform line height treat a new line as expected editing. A user who tapped “load more” and stays at the original viewport is requesting an append; it is not an interruption if original line coordinates hold.
Applying it
- Default async modules for articles, docs, and settings to below the current viewport or outside the main column; do not inject between the current paragraphs unsolicited.
- Infinite lists append at the bottom with scroll anchoring; do not insert above already-read items and push the row being read out of view.
- Required notices use a rail, a bottom bar, or an overlay—not the mid-flow of the reading surface.
- Verify by injecting a recs module while the reader is mid-article; the current paragraph’s viewport Y should not change. For upward history loads, the original first row should keep its viewport slot.
Related
- Same group: R3.05.1 Late-arriving content pushes already laid-out nodes · R3.05.2 Displacement causes misclicks · R3.05.3 Dynamic content needs reserved space · R3.05.4 Render-blocking resources determine the first visible moment · R3.05.5 Already-interactive regions must not be reflowed by late content
- Adjacent: I2.07 Perceived performance · I2.01 Choosing skeleton versus spinner
- Search terms:
scroll anchoring·async insertion·reading position
Cards in the same group
- R3.05.1Late-arriving content pushes already laid-out nodes
- R3.05.2A control that moves after render steals the tap meant for it
- R3.05.3Dynamic content needs reserved space
- R3.05.4Render-blocking resources determine the first visible moment
- R3.05.5Already-interactive regions must not be reflowed by late content