Welcome

Superfast Scroll

A practice demo for getting familiar with svelte.

Demo

Virtual Scroll List Demo

Initializing list items...

I’m new to Svelte. This practice demo is for me to getting familiar with svelte store and reactive programming.

Technical Notes

This high-performance virtual scroll implementation combines battle-tested techniques with some experimental spice:

1. Data Structure Shenanigans

Our demo rides on a SkipList - not because it’s optimal, but because why not? (Confession: Your author just wanted an excuse to implement one 🎒)

  • SkipList delivers O(log n) for search/insert/delete
  • Reality check: A simple array + index map would smoke it for this use case (O(1) lookups)
  • To spice things up, we added artificial delays (200ms) in data fetching. Did you notice? πŸ˜‰

2. Ring Buffer Tango

We perform a carefully choreographed dance between two circular buffers:

DOM Recycling Ring

  • domRingHead + modulo arithmetic = infinite scrolling illusion
  • Extra buffer elements prevent visual hiccups
  • Reuses a limited number of DOM nodes, significantly reducing memory usage and DOM operations

Data Window Provider Ring Buffer

  • Provides buffering for asynchronous data loading
  • Maintains upper and lower buffer zones for preloading and smooth scrolling
    • Doubly-linked list enables O(1) window sliding

3. The Trilogy of Scroll Evolution

Version 1: The Sync Era πŸš€

Status: Deprecated but Nostalgic
Our initial β€œeverything works” prototype:

  • Built for instant data access (latency comes from time complexity of data source implementation)
  • Handle 100k items? Easy peasy lemon squeezy!
  • Use same logic for both scroll and jump:
    • Flow: User input β†’ Position update β†’ Provider processes data β†’ Provider publishes new version β†’ UI listens for version changes and fetches data

Version 2: Async Apocalypse πŸ’₯

Status: Briefly Lived Disaster

When we introduced async data loading in the data window provider (no actual delays added in data source):

  • Sync logic met async reality β†’ πŸ’£

  • UI started shifting

  • translateY, domRingHead, and data updates entered a love triangle

Version 3: Redemption Arc 🦸

  • Separated the logic for incremental scrolling and jumping again
    • Incremental scrolling: uses a more direct and efficient approach, manipulating the DOM ring buffer and data directly to maintain visual continuity.
  • Jumping: Completely resets the view state and waits for asynchronous data loading to complete

4. TranslateY Dual-Purpose Implementation

  1. Container-level translateY:

    • Applied to the entire list container
    • The smooth talker: creates scrolling illusion
    • Incrementally updated then reset like nothing happened
  2. Item-level translateY:

    • Applied to individual list items
    • Items maintain fixed translateY values until recycled
    • The precision artist: translateY = (mappedIndex Γ— itemHeight)
    • DOM elements play musical chairs without moving physically

This dual-transform approach enables several key optimizations:

  • Minimizes DOM manipulation by changing only transform properties
  • Avoids expensive reflow/repaint cycles in the browser
  • Leverages GPU acceleration for smooth animations
  • Allows for precise pixel positioning without layout calculations

Final score: 60 FPS smooth scrolling with 100k+ items (even with delays). Try that with standard lists 😎