Summary
Add a built-in lazy rendering / range virtualization mechanism for row-based layouts (e.g., shelves of posters) in react-lightning, similar to the LazyRow primitive implemented in @lightningtv/solid.
This would significantly improve performance in Smart TV environments, where rails can contain hundreds of items, but only a small subset is visible at any time.
Problem
When building Smart TV interfaces with rails/shelves (Netflix-style UI), a common pattern is:
Home
├─ Row 1 (20–50 items)
├─ Row 2 (20–50 items)
├─ Row 3 (20–50 items)
├─ Row 4 (20–50 items)
In real applications, this can easily reach 300–500 items on a single screen.
Currently, when rendering rows with react-lightning:
-
all components are created immediately
-
all images begin loading immediately
-
rendering cost scales linearly with item count
Example:
8 rows × 60 items = 480 cards
This causes:
-
large number of network requests
-
high GPU memory usage
-
slower initial render time
-
worse performance on older TVs
In one real-world case we observed:
Expected Behavior
Rows should support lazy rendering, meaning:
Only render items that are:
Example:
Visible range: 0–7
Buffer: +3
Rendered items: 0–10
When the user navigates right:
focus moves → expand rendered range
But never shrink the range when navigating back, to avoid destroying and recreating components.
This spreads rendering and image loading over time.
Reference Implementation (Solid)
The Solid Lightning primitives already implement this pattern:
@lightningtv/solid/primitives/LazyRow
Core idea:
Where offset increases when navigation approaches the end of the rendered items.
Example usage:
<LazyRow
display="block"
gap={20}
upCount={5}
each={activeRow()?.items()}
>
{(item, index) => <Poster {...item()} />}
</LazyRow>
Key behavior:
-
render first N items
-
increase render window when navigation approaches edge
-
never shrink when navigating back
-
optionally preload items progressively
Proposed API (React)
Something similar could be introduced for react-lightning:
<LazyRow
items={items}
initialCount={8}
buffer={3}
increment={4}
renderItem={(item, index) => (
<Poster item={item} />
)}
/>
Behavior:
initialCount = items rendered initially
buffer = threshold before expanding
increment = number of items to add
Internally:
visibleItems = items.slice(0, visibleCount)
When navigation reaches:
selectedIndex >= visibleCount - buffer
Then:
visibleCount += increment
Why This Matters for Smart TVs
Smart TVs often run:
-
Chromium v51–v70
-
low memory
-
slow GPUs
-
weak CPUs
Rendering hundreds of elements at once causes:
-
dropped frames
-
slow startup
-
network congestion
Lazy row rendering dramatically improves:
Metric | Improvement
-- | --
Initial page load | 3–5× faster
Memory usage | 70–80% reduction
Network requests | 80–90% reduction on initial load
Alternative Approach (Renderer Level)
Lightning renderer already supports viewport bounds detection (inViewport, outOfBounds, etc.).
Another option could be:
However, row-level lazy rendering is still extremely valuable because it prevents component creation entirely, not just rendering.
Suggested Implementation
Options:
Option 1
Add a LazyRow component to react-lightning.
Option 2
Add range virtualization support to Row.
Example:
<Row range={{ from: 0, to: focusIndex + buffer }}>
Option 3
Expose a helper hook:
Real-world Example
A typical TV home screen:
Home
Row 1 40 items
Row 2 50 items
Row 3 40 items
Row 4 60 items
Row 5 30 items
Total:
With lazy rows:
initial render ≈ 40–60 items
instead of 220.
Additional Benefit
Lazy rows also allow:
Related Work
Solid Lightning implementation:
@lightningtv/solid/primitives/LazyRow
Lightning Blits documentation:
Summary
Add a built-in lazy rendering / range virtualization mechanism for row-based layouts (e.g., shelves of posters) in
react-lightning, similar to theLazyRowprimitive implemented in@lightningtv/solid.This would significantly improve performance in Smart TV environments, where rails can contain hundreds of items, but only a small subset is visible at any time.
Problem
When building Smart TV interfaces with rails/shelves (Netflix-style UI), a common pattern is:
In real applications, this can easily reach 300–500 items on a single screen.
Currently, when rendering rows with
react-lightning:all components are created immediately
all images begin loading immediately
rendering cost scales linearly with item count
Example:
This causes:
large number of network requests
high GPU memory usage
slower initial render time
worse performance on older TVs
In one real-world case we observed:
500+ image requests on page load
1600+ requests when scrolling across rows
Expected Behavior
Rows should support lazy rendering, meaning:
Only render items that are:
Example:
When the user navigates right:
But never shrink the range when navigating back, to avoid destroying and recreating components.
This spreads rendering and image loading over time.
Reference Implementation (Solid)
The Solid Lightning primitives already implement this pattern:
Core idea:
Where
offsetincreases when navigation approaches the end of the rendered items.Example usage:
Key behavior:
render first N items
increase render window when navigation approaches edge
never shrink when navigating back
optionally preload items progressively
Proposed API (React)
Something similar could be introduced for
react-lightning:Behavior:
Internally:
When navigation reaches:
Then:
Why This Matters for Smart TVs
Smart TVs often run:
Chromium v51–v70
low memory
slow GPUs
weak CPUs
Rendering hundreds of elements at once causes:
dropped frames
slow startup
network congestion
Lazy row rendering dramatically improves:
Alternative Approach (Renderer Level)
Lightning renderer already supports viewport bounds detection (
inViewport,outOfBounds, etc.).Another option could be:
automatic node skipping when outside render bounds
optional preload margins
However, row-level lazy rendering is still extremely valuable because it prevents component creation entirely, not just rendering.
Suggested Implementation
Options:
Option 1
Add a LazyRow component to
react-lightning.Option 2
Add range virtualization support to
Row.Example:
Option 3
Expose a helper hook:
Real-world Example
A typical TV home screen:
Total:
With lazy rows:
instead of 220.
Additional Benefit
Lazy rows also allow:
progressive image loading
smoother navigation
better CPU distribution
faster first paint
Related Work
Solid Lightning implementation:
Lightning Blits documentation: