Packages

Firelight.Virtualizer

Render long lists quickly by keeping only the visible items in the DOM.

Why use it

A list of ten thousand rows is ten thousand DOM elements, which are slow to create and make the page heavy to scroll. The virtualizer renders only the items in view, plus a few either side, and reuses them as you scroll, so the cost stays about the same however long the list gets.

Use the Virtualizer.virtualize directive inside your own scrolling element, as below, or register the <lit-virtualizer> element with Virtualizer.defineElement (). A handle from Virtualizer.get can scroll to any item, even one that isn't rendered yet.

Example

Ten thousand rows. Open your browser's developer tools on the list: only the rows near the visible ones exist in the DOM.

module Snippets.BigList

open Fable.Core
open Firelight
open Firelight.Virtualizer
open type Firelight.Lit

let rows = [| for i in 1..10_000 -> $"Row {i}" |]

let private row = RenderItem<string>(fun text _ -> html $"<li>{text}</li>")

/// Ten thousand rows, but only the ones in view exist in the DOM.
[<AttachMembers>]
type BigList() =
    inherit LitElement()

    static member styles =
        css
            $$"""
        :host { display: block; width: 100%; }
        ul {
            height: 16rem; overflow: auto; margin: 0; padding: 0; list-style: none;
            border: 1px solid var(--border); border-radius: 0.5rem; background: var(--bg);
        }
        li { width: 100%; padding: 0.4rem 0.75rem; border-bottom: 1px solid var(--border); }
        """

    override _.render() =
        html
            $"""<ul tabindex="0" aria-label="Ten thousand rows">{Virtualizer.virtualize (VirtualizeConfig(rows, row, scroller = true))}</ul>"""

defineElement<BigList> "my-big-list"

Install

dotnet add package Firelight.Virtualizer
npm install @lit-labs/virtualizer