Building Globdrop: Tech Stack & Performance Engineering
In modern web development, there is a strong default tendency to reach for heavy, single-page application (SPA) frameworks like React, Next.js, or Angular. While these tools excel at complex, data-heavy enterprise dashboards, they carry a hidden cost: bundle bloat, virtual DOM overhead, and increased CPU usage. When building an interactive browser game, these costs directly manifest as input lag, visual stuttering, and slow loading times—especially on mobile devices.
When we designed Globdrop, our multi-scenario geography quiz, we decided to take a different path. We set a strict budget: sub-second load times under 3G networks and a constant 60 frames per second (fps) render rate during animations. To achieve this, we built a custom game engine using TypeScript and vanilla DOM manipulation, powered by a modern, ultra-fast build toolchain. Here is an architectural deep dive into our stack.
The Core Architecture
Globdrop is built on a clean separation of concerns: state management, coordinate projection, rendering, and asset caching. Instead of using a framework to track and diff UI states, we use a lightweight, event-driven state machine written in native TypeScript.
TypeScript & Vite
Type safety and fast bundling with hot-module reloading during development. Minimal runtime compilation overhead.
Vanilla DOM & CSS
Direct interaction with DOM APIs and Hardware-accelerated CSS transforms. No virtual DOM diffing latency.
SVG Coordinate Projection
Lightweight, scalable vector maps that adapt to any screen size without resolution loss or pixelation.
Service Worker PWA
Caches game maps, assets, and localization text offline, enabling near-instantaneous subsequent loads.
Why Vanilla TypeScript over React/Vue?
A round of Globdrop is highly interactive. The player clicks, an arrow vector is drawn from their click to the target location, a scoring counter ticks up rapidly, and the map pans and zooms. If this were built in React, every tick of the score and coordinate update would trigger component renders, reconciliation, and virtual DOM calculations.
In Globdrop, we manipulate the DOM directly. For example, during the tick of the score animation, we target the element ID and modify its text content inside a requestAnimationFrame loop:
// Direct, high-performance animation frame ticking
function animateScore(targetScore: number, duration: number) {
const scoreElement = document.getElementById('score-value');
if (!scoreElement) return;
const start = performance.now();
const startScore = parseInt(scoreElement.innerText) || 0;
function update(now: number) {
const elapsed = now - start;
const progress = Math.min(elapsed / duration, 1);
// Ease-out cubic calculation
const currentScore = Math.floor(startScore + (targetScore - startScore) * (1 - Math.pow(1 - progress, 3)));
scoreElement.innerText = currentScore.toLocaleString();
if (progress < 1) {
requestAnimationFrame(update);
}
}
requestAnimationFrame(update);
} This approach bypasses all framework layers, running directly at the browser's native rendering rate. This leaves the CPU completely free to handle map projections and responsive inputs.
SVG Maps and Coordinate Math
One of the most complex challenges in Globdrop is translating a user's click coordinate on an SVG map element to its actual geographic latitude and longitude. Many games load huge satellite imagery libraries, but these are heavy and require active internet requests.
Globdrop uses customized, highly simplified GeoJSON files converted to SVG paths. Because SVG paths are mathematical descriptions, they scale infinitely with crisp borders. To map coordinates, we use a simple linear projection calculation based on bounding boxes. During map construction, we establish the bounding box of the SVG (in SVG coordinate units) and align it with the geographic bounds of the scenario (latitude and longitude boundaries):
// Simple geographic bounding box interpolation
export function projectCoords(
x: number, y: number,
svgWidth: number, svgHeight: number,
geoBounds: { minLng: number, maxLng: number, minLat: number, maxLat: number }
) {
// Convert SVG coordinates (0 to width/height) to relative percentages
const pctX = x / svgWidth;
const pctY = y / svgHeight;
// Interpolate longitude (linear)
const lng = geoBounds.minLng + pctX * (geoBounds.maxLng - geoBounds.minLng);
// Interpolate latitude (reversing Y-axis as SVG runs 0 down, Geo runs 0 up)
const lat = geoBounds.maxLat - pctY * (geoBounds.maxLat - geoBounds.minLat);
return { lat, lng };
} This allows us to run extremely fast distance checks using the Haversine formula completely client-side in less than a millisecond, calculating the exact offset in kilometers and updating the score immediately.
Performance Metrics & Results
By keeping our codebase lean and avoiding unnecessary frameworks, Globdrop achieves industry-leading performance benchmarks:
- Initial Bundle Size: Under 45KB (gzipped), including game logic, SVG rendering engine, and the state controller.
- Largest Contentful Paint (LCP): 0.6 seconds on standard 4G connections.
- Input Latency: Less than 4ms, ensuring that clicking the map feels immediate and fluid.
- Frame Rate: Constant 60fps on mobile Safari and Chrome, even during screen transitions and map zooming.
Looking Forward
Our experience building Globdrop proves that vanilla web engineering is not only viable but superior for high-performance interactive experiences. As we build out multiplayer modes and custom map builders, we will continue to prioritize lean architecture and direct DOM rendering to keep our games accessible to everyone on any device.