Why God's Eye View Caps Its Render Loop at 60 fps: Performance Deep Dive

God's Eye View explicitly limits Cesium JS's render loop to 60 fps in src/main.js to cut GPU/CPU usage by roughly 50% on high-refresh displays while maintaining smooth visual animations that are driven by wall-clock time rather than frame count.

God's Eye View (GEV) is a web-based geospatial visualization application built on Cesium JS. While modern displays—including macOS ProMotion panels—can refresh at 120 Hz or higher, the application enforces a strict 60 fps render loop cap to optimize performance and battery life without degrading the user experience.

The Technical Rationale Behind the 60 fps Cap

Cesium JS defaults to rendering at the display's native refresh rate. On high-end hardware, this can mean 120 Hz or even 240 Hz, which significantly increases resource consumption for a visualization tool where animations are calculated against real-time intervals rather than frame progression.

Cesium JS Default Behavior vs. GEV Requirements

By default, Cesium's Viewer attempts to match the monitor's refresh rate. On a 120 Hz display, this doubles the render workload compared to a standard 60 Hz monitor. However, GEV's visual updates—including camera interpolation, trail fading, and style cross-fades—operate on wall-clock time. This means the animation progress is calculated based on elapsed milliseconds, not the number of frames rendered.

Rendering 120 frames per second provides zero visual benefit when the underlying data updates and interpolations are timed to real-world seconds. The extra frames simply display identical intermediate states, wasting computational resources.

Wall-Clock Animation Timing

The application's animation system uses time-based deltas rather than frame-based stepping. Whether the render loop executes 60 times or 120 times per second, a one-second camera fly-to animation completes in exactly one second. The 60 fps cap ensures consistent timing across all devices while eliminating redundant draw calls on high-refresh hardware.

Performance Impact and Energy Efficiency

The explicit frame rate limitation delivers measurable benefits across three key areas:

  • GPU/CPU Utilization – According to performance investigations documented in the codebase, forcing targetFrameRate = 60 achieves a strict halving of idle burn on 120 Hz hardware compared to uncapped rendering. The skipped frames reduce computational overhead without dropping visual frames that matter.

  • Visual Consistency – Capping the rate guarantees that animation cadence remains stable across devices regardless of monitor capabilities. A user on a 60 Hz display sees identical timing to a user on a 240 Hz gaming monitor.

  • Battery Conservation – Lowering the render rate directly reduces power draw on laptops and mobile devices. For an application designed to run continuously monitoring geospatial data, this optimization extends battery life significantly during extended viewing sessions.

Implementation Details in the Codebase

The frame rate restriction is implemented explicitly in the main application initialization with detailed inline documentation explaining the engineering decision.

The Core Implementation in src/main.js

In src/main.js (lines 120–128), the Viewer instance is configured with the performance cap immediately after initialization:

// Cap the default render loop at 60 fps. Cesium's loop otherwise runs at
// the display's refresh rate — 120 Hz on ProMotion panels — doubling GPU
// and CPU burn for zero visual benefit in a map app whose animation
// cadences (poll interpolation, trail fades, style crossfades) are all
// designed against wall-clock time, not frame count. Measured on the
// 2026-08-05 perf investigation as a strict halving of idle burn on
// 120 Hz hardware; a no-op on 60 Hz displays. (perf item 2)
viewer.targetFrameRate = 60;

This assignment overrides Cesium's internal requestAnimationFrame timing, forcing the engine to skip renders when the display refreshes more frequently than 60 Hz.

Integration with the Render Governor

The frame rate cap works alongside the render governor system located in src/renderGovernor.js. While the governor can request on-demand renders for data updates or user interactions, the 60 fps maximum prevents unnecessary continuous rendering during idle states. This dual system ensures the map responds immediately to changes without maintaining a wasteful constant render loop.

Configuring the Frame Rate Cap

Developers working with the GEV codebase or building custom Cesium applications can modify this behavior for specific use cases.

Setting a lower cap for extreme power-saving mode:

import { Viewer } from 'cesium';

const viewer = new Viewer('cesiumContainer');
viewer.targetFrameRate = 30;   // Limit to 30 fps for ultra-low-power mode

Removing the cap entirely (not recommended for production):

viewer.targetFrameRate = undefined; // Defaults to display refresh rate

Reverting to an uncapped state restores Cesium's default behavior, which may be suitable for debugging or specialized high-frequency data visualization but will increase energy consumption proportionally to the display's refresh rate.

Summary

  • The 60 fps render loop cap in src/main.js prevents Cesium JS from rendering at the display's native refresh rate (120 Hz or higher).
  • This optimization reduces GPU and CPU idle burn by approximately 50% on high-refresh hardware while maintaining identical visual output.
  • All animations in God's Eye View use wall-clock timing, making frame rates above 60 fps redundant for visual fidelity.
  • The cap integrates with src/renderGovernor.js to balance responsiveness with energy efficiency.
  • Developers can adjust viewer.targetFrameRate for custom power profiles but should retain the 60 fps limit for production deployments targeting battery-powered devices.

Frequently Asked Questions

Why does God's Eye View use 60 fps instead of matching the display's refresh rate?

God's Eye View limits rendering to 60 fps because the application's animations—such as camera movements and data trail fades—are calculated based on elapsed time rather than frame progression. Rendering at 120 Hz on a ProMotion display would consume twice the GPU/CPU resources to display identical intermediate animation states, providing no visual benefit while significantly increasing power consumption and heat generation.

Does capping the render loop affect animation smoothness?

No, the cap does not impact perceived smoothness because GEV's animation system relies on delta time calculations rather than fixed frame steps. A camera interpolation that takes one second to complete executes over 60 frames at the capped rate versus 120 frames at an uncapped rate, but both complete in exactly one second with identical easing curves. The visual output remains consistent across all display types.

How does the frame rate cap interact with the render governor system?

The frame rate cap in src/main.js establishes a maximum bound for the render loop, while the render governor in src/renderGovernor.js manages when renders are actually requested. The governor can trigger renders on demand for data updates or user interactions, but it cannot exceed the 60 fps limit set by targetFrameRate. This combination ensures the application never wastes cycles on unnecessary frames while remaining responsive to real-time events.

Can I disable the 60 fps cap for high-refresh gaming monitors?

While you can disable the cap by setting viewer.targetFrameRate = undefined, this is not recommended for production use. The change would force the GPU to render frames that provide no visual improvement in a geospatial mapping context, effectively doubling or tripling power consumption on high-refresh displays. If you require higher frame rates for specific debugging or profiling scenarios, ensure you re-enable the cap before deploying to battery-powered devices.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →