Just F* useWebGL
Embedded devices struggle with modern web rendering.
The CPU is simply too weak to handle complex DOM layouts.
Unleash the GPU. Use WebGL for buttery smooth 60fps interfaces.
Why WebGL?
Traditional DOM rendering is like moving rocks by hand.
WebGL is using a fleet of nuclear-powered dump trucks.
Retained Mode (DOM)
- ✕The Pixel Pipeline TaxStyle Recalc, Layout (Reflow), and Paint are performance killers on weak CPUs.
- ✕Layout ThrashingSynchronous reflows caused by reading layout properties (offset, clientRect) break the render loop.
- ✕Cache MissesTraversing large DOM trees on Cortex-A55 cores triggers frequent L2 cache misses.
Immediate Mode (WebGL)
- ✓Bypass Layout & PaintSkip the browser's heavy layout engine. Draw directly to the GPU.
- ✓Zero-Cost ShadersPer-pixel effects (blur, glow) run in parallel on the GPU, not the CPU.
- ✓Massive ParallelismAnimate thousands of sprites @ 60fps where the DOM struggles with dozens.
Smart TVs Are Slow
Your $2000 TV has a $5 processor. DOM animations make it cry.
WebGL runs natively on its GPU, bypassing the chaotic CPU entirely.
The Silicon Reality
The Amlogic S905X4 (common in Android TV) uses a Quad-core Cortex-A55 CPU. It is built for power efficiency, not for heavy JavaScript parsing or complex DOM trees.
Traversing a large DOM tree causes constant L2 cache misses, while the powerful Mali-G31 GPU sits idle, waiting for commands.
[Violation] 'requestAnimationFrame' handler took 150msHardware Truths
- ⚡Memory Bandwidth Starvation4K UI framebuffers (~33MB) consume 2GB/s of bandwidth, starving the CPU.
- ⚡Layer ExplosionCreating too many composite layers crashes low-end STBs (Realtek RTD1319).
- ⚡Garbage CollectionFrequent "Stop-the-World" GC pauses (100ms+) cause massive frame drops.
Silicon Constraints
To build for TV, you must understand the hardware. It is fundamentally asymmetric: strong video decoding, weak general-purpose computing.
The CPU Bottleneck
Cortex-A55 @ 2.0GHz
- In-Order Execution
Unlike desktop CPUs, the Cortex-A55 processes instructions sequentially. Heavy JS parsing or JIT compilation blocks the pipeline immediately.
- Cache Misses
Traversing a DOM tree with 2,000 nodes triggers frequent L2 cache misses, stalling the processor while it waits for system memory.
The GPU Opportunity
Mali-G31 MP2 / G52
Massive Parallelism
Architected for pixel shading and texture mapping. Capable of billions of operations per second, often sitting idle in DOM applications.
Why WebGL Wins
By offloading geometry and pixel calculations to the GPU, we unlock the only truly performant component of the TV SoC.
The 4K Memory Tax
A single 4K framebuffer requires ~33MB. At 60fps, moving this data consumes 2 GB/s of memory bandwidth. On shared-memory architectures (2GB Total RAM), this starves the CPU.
*Realtek RTD1319 / Broadcom BCM7271 often rely on slower DDR3 interfaces, making this critical.
Technical Deep Dive
Typography (SDF)
Browser font engines (HarfBuzz) are heavy. In WebGL, we use Signed Distance Fields (SDF) or MSDF.
Instead of pixels, we store distance-to-edge values. This allows for infinite scaling without blurriness, perfect for 4K TV interfaces.
Memory & GC
TVs often share 2GB RAM between OS, Video Decoder, and App.
React's Virtual DOM creates thousands of objects. On low-end hardware, this triggers 100ms+ GC pauses. Frameworks like LightningJS (v3) or careful PixiJS usage allow for static memory allocation.
The WebGL Tax
Abandoning the DOM means losing "free" features.
Accessibility (Screen Readers), Focus Management, and International text rendering must be rebuilt from scratch. It is the cost of raw performance.
Framework Ecosystems
React + PixiJS
The Hybrid Choice
For teams with deep React expertise, adopting @pixi/react is a compelling middle ground. It allows using declarative JSX to drive a high-performance WebGL renderer.
The reconciliation process runs on the CPU. Diffing the Virtual DOM for high-frequency updates (like 60fps animations) can overload the Cortex-A55.
Optimization: Bypass React for animations. Use the PixiJS Ticker directly or imperative refs.
Spatial Navigation
- norigin-spatial-navigation: Robust, but relies on expensive DOM measurements.
- react-tv-space-navigation: Declarative, faster, but can have edge cases with virtualization.
Why not Three.js (R3F)?
Overkill for 2D. Three.js materials and geometries are heavy. On 2GB RAM devices, the overhead reduces image cache headroom and can cause stability issues (leaks).
LightningJS
The Specialist Choice
LightningJS rejects the DOM entirely in favor of a "Game Engine" model. It maintains a lightweight Render Tree of simple JS objects, free from browser baggage.
L3 decouples the renderer. The official Blits framework provides a lightweight, Vue-like syntax optimized specifically for TV interfaces, eliminating the Virtual DOM entirely.
The "Focus Path"
Unlike bubbling events, Lightning uses a Focus Path. Key events are delivered directly to the active component. This eliminates "focus trap" bugs and makes navigation logic extremely predictable.
Architectural Decision Matrix
Why choose hybrid: The massive gain in developer velocity from using the React ecosystem outweighs the small runtime performance cost compared to a specialized engine.
| Feature | React (DOM) | RECOMMENDED React + PixiJS | LightningJS (Blits) |
|---|---|---|---|
| Pipeline | Browser Layout/Paint (CPU Heavy) | WebGL Immediate (GPU) | WebGL Immediate (GPU) |
| Dev Velocity | High (React) | High (React) | Low (Custom DSL) |
| Animations | Poor on STBs | Good (if optimized) | Excellent (Native) |
| Memory | High (DOM Nodes) | Medium | Low (Optimized) |
| Ecosystem | Massive | Large | Niche |
| Text Quality | Native / Perfect | SDF Required | SDF Required |
| Target HW | High-end Only | Mid-to-High | All (Low-to-High) |