Meliora Mirror: Keeping a Widget Grid Smooth on a Raspberry Pi
The widget grid rendering live weather, calendar, and transit data on-device.
Part 1: Introduction
1.1 The Problem
The UX direction called for a strict information hierarchy that updates constantly — weather, time, calendar, transit, stocks — all live, all rendering on a Raspberry Pi with a fraction of the GPU headroom of a laptop or phone. The frontend question wasn’t “how do we build this in React,” it was how do we keep a data-heavy interface smooth on hardware that wasn’t built for it, running 24/7 without a restart.
1.2 Constraints, Stated Up Front
- Constrained hardware. A Pi-class device driving a full-screen display has meaningfully less headroom than typical target devices for a web app — every re-render has a real cost.
- Always-on runtime. The app doesn’t get refreshed daily like a browser tab. It has to run for weeks without a memory leak degrading it.
- Independent data cadences. Weather updates every few minutes, transit every 30 seconds, calendar rarely, time every second. Naively re-rendering the tree on any change would mean the whole screen redraws every second.
- No dev tools on the actual device. Debugging performance issues meant reasoning from Chrome DevTools on a desktop, then verifying separately on-device, since profiling tools don’t run well on the Pi itself.
Part 2: Component Architecture
Design goal: each widget owns its data lifecycle and re-render boundary — nothing shares a subtree it doesn’t need to.
The screen is composed of independent widgets (ClockWidget, WeatherWidget, CalendarWidget, TransitWidget, StocksWidget) mounted into a fixed grid layout, not a single monolithic dashboard component. Each widget:
- Manages its own polling interval, matched to how often its data actually changes.
- Subscribes only to its own slice of state.
- Renders independently — a clock tick shouldn’t touch the calendar widget’s subtree.