Skip to content

feat: add NaiveList, a minimal virtualized list - #1

Merged
mdjastrzebski merged 17 commits into
mainfrom
claude/minimal-flat-list-api-mkmand
Oct 6, 2026
Merged

mdjastrzebski merged 17 commits into
mainfrom
claude/minimal-flat-list-api-mkmand

Conversation

@mdjastrzebski

@mdjastrzebski mdjastrzebski commented Oct 3, 2026 •

Copy link
Copy Markdown
Owner

Summary

Adds NaiveList, the simplest possible virtualized list. Its API is only the core props: data and renderItem({ item, index }).

  • A vertical ScrollView tracks the scroll offset (onScroll, throttled to 16 ms) and the viewport height (onLayout).
  • computeRenderWindow renders the items that overlap the viewport plus one viewport of buffer above and below. A top and a bottom spacer view stand in for everything else.
  • Each item is wrapped in a View whose onLayout caches its height by index. A changed height triggers a re-render. Unmeasured items count as 50 px.
  • Items are keyed by index, so no keyExtractor is needed.

Known limitations (by design)

  • Blank areas and content jumps when scrolling fast or when the 50 px estimate is off.
  • The first frame is empty until the viewport is measured.
  • Cached sizes are keyed by index, so they are wrong after inserts or reorders until those items are re-measured.
  • Every scroll event re-renders the whole list.

Other changes

  • Removed the template multiply export.
  • The example app now renders 10,000 variable-height rows with NaiveList.
  • README usage section updated.
  • Added yarn.lock.

Testing

  • yarn typecheck, yarn lint and yarn test pass.
  • Unit tests cover computeRenderWindow only. There is no React test renderer in the dev dependencies, so the component itself is untested.
  • Not run on a device or simulator yet.

claude and others added 13 commits October 3, 2026 10:49
Renders only items within one viewport of the visible area inside a
vertical ScrollView, with spacer views for the rest. Item heights are
measured via onLayout and cached by index. API is data + renderItem.

Replaces the template multiply() export.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QF2dLjvFKnpAYNPcoNDHLg
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QF2dLjvFKnpAYNPcoNDHLg
The last step of a drag scroll is reported only by onScrollEndDrag, not
onScroll, so the render window lagged behind where scrolling stopped.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QF2dLjvFKnpAYNPcoNDHLg
Adds @testing-library/react-native v14 and test-renderer, and covers
renderItem args, windowing, scrolling, measured sizes and empty data.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QF2dLjvFKnpAYNPcoNDHLg
Extract computeRenderWindow, RenderWindow and DEFAULT_ITEM_SIZE into
renderWindow.ts and colocate tests with the component.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QF2dLjvFKnpAYNPcoNDHLg
Readability and clear core virtualization ideas take priority over
performance, for both human contributors and agents.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QF2dLjvFKnpAYNPcoNDHLg
Binary search, memoization and better structure are preferred, as long
as each technique is extracted into a well-named function so the code
stays easy to follow.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QF2dLjvFKnpAYNPcoNDHLg
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QF2dLjvFKnpAYNPcoNDHLg
claude and others added 4 commits October 4, 2026 12:39
Covers the spacer + render window idea step by step, known flaws, and
which FlatList features are and aren't implemented.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QF2dLjvFKnpAYNPcoNDHLg
@mdjastrzebski
mdjastrzebski merged commit 64f8a87 into main Oct 6, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants