Real stories:How a football-school coach shipped his apps in one week soon

10,000 rows

UIVirtualizedList mounts only the rows near the viewport, so ten thousand of them scroll as cheaply as ten. Data is imperative — build the array once and setData it; the list recycles row elements as you scroll, so render must depend only on the item it's given.

Fork in le.codes
// UIVirtualizedList mounts only the rows near the viewport, so 10,000 items scroll as cheaply
// as ten. Data is driven imperatively — build the array once and setData it; the list recycles
// row elements as you scroll. render() must be pure over its item, so the row reads only `r`.
type Row = { id: number, name: string, weight: number }

const NAMES = ["Helium", "Carbon", "Neon", "Argon", "Iron", "Copper", "Zinc", "Krypton", "Xenon", "Radon"]
const rows: Row[] = Array.from({ length: 10000 }, (_, i) => ({
    id: i,
    name: `${NAMES[i % NAMES.length]} ${String(i + 1).padStart(4, "0")}`,
    weight: Mathf.randomInt(1, 300),
}))

const list = UIVirtualizedList<Row>({
    keyOf: r => String(r.id),
    estimatedHeight: 64,
    render: r => UIRow([
        UIColumn([
            UIText(r.name).style({ fontSize: 16, color: "white" }),
            UIText(`#${r.id + 1}`).style({ fontSize: 12, color: "#5c6272" }),
        ]).style({ gap: 2 }),
        UISpacer(),
        UIText(`${r.weight} g`).style({ fontSize: 15, color: "#8b90a0", fontFamily: "monospaced" }),
    ]).style({ height: 64, px: 20, alignItems: "center", borderBottom: "1px solid #171b24" }),
}).style({ flexGrow: 1 })
list.setData(rows)

const screen = UIScreen([
    UIColumn([
        UIText("Elements").style({ fontSize: 28, fontWeight: 700, color: "white" }),
        UIText(`${rows.length.toLocaleString("en-US")} rows, windowed`).style({ fontSize: 13, color: "#8b90a0" }),
    ]).style({ bgColor: "#0b0d12", px: 20, pt: "max(safe-top, 24px)", pb: 14, gap: 2 }),
    list,
]).style({ bgColor: "#0b0d12" })

screen.open()

Related docs