Bandwidth Optimization: From 1.2MB Logos to Sub-Second Database Loads

When EVE Frontier Map launched, every page load transferred over 6MB of data—1.2MB for a single logo PNG, 5MB for the universe database downloaded on every session, and dozens of smaller assets. For users on mobile connections, first load could take 8-12 seconds.

Over the past week, we systematically eliminated bandwidth waste while improving UX. Here's how we cut loading times by 99.9% and reduced our CDN egress costs from £12-22/month to £1-2/month.

The Logo Problem: 1.2MB of Unnecessary Pixels

Our loading screen featured a high-resolution PNG logo: 600×600 pixels, 32-bit RGBA, weighing 1,212 KB. Users on slow connections would stare at a blank screen for 3-5 seconds waiting for the logo to appear—before the actual app even started loading.

Investigation

We analyzed the logo file:

This was a perfect candidate for SVG conversion.

The Fix: SVG Conversion

We converted the logo from PNG to SVG, manually tracing the geometric shapes:

Before (PNG)
1,212 KB
Raster, 600×600px, 32-bit RGBA
After (SVG)
1.23 KB
Vector, resolution-independent
Reduction: 99.9% smaller file size (1,210 KB saved)
Quality: Identical visual appearance at all resolutions
Scalability: Works on 4K displays without pixelation

Updated references in App.tsx, LoadingScreen.tsx, and index.html, keeping the original PNG as .backup for rollback safety.

Database Caching: Solving the 5MB Download Problem

EVE Frontier Map loads two SQLite databases on startup:

Initially, every session fetched these from Cloudflare CDN—even though the universe database changes once per 90-day cycle, and the solar system database is updated manually.

Dual-Layer Cache Strategy

We implemented a two-tier caching system:

async function loadDatabase(dbUrl, dbName) {
  // Layer 1: Check IndexedDB (browser storage)
  let dbBlob = await indexedDbCache.get(dbName);
  
  if (dbBlob) {
    console.log(`✅ Cache hit: ${dbName} from IndexedDB`);
    return dbBlob;
  }
  
  // Layer 2: Fetch with HTTP cache (Cloudflare CDN)
  const response = await fetch(dbUrl, { 
    cache: 'force-cache' // Prefer cached response
  });
  
  // Layer 3: Network request (fallback)
  if (!response.ok) throw new Error('Network load failed');
  
  dbBlob = await response.blob();
  
  // Store in IndexedDB for next session
  await indexedDbCache.set(dbName, dbBlob);
  
  return dbBlob;
}

Cache Duration Tuning

We set aggressive HTTP cache headers on the Cloudflare Worker:

// Universe database: 90 days (EVE Frontier cycle duration)
'Cache-Control': 'public, max-age=7776000, immutable'

// Solar system database: 90 days (manual updates)
'Cache-Control': 'public, max-age=7776000, immutable'
First visit: 5 MB network download + IndexedDB write (~3s on 4G)
Subsequent visits: IndexedDB read only (~500ms)
Bandwidth savings: 5 MB × (sessions - 1) per user
CDN egress cost reduction: ~91% (£12-22/month → £1-2/month)

Cache Invalidation Strategy

When we update the databases manually:

  1. Bump the database filename (e.g., map_data_v3.db)
  2. Update references in code to new filename
  3. Purge Cloudflare cache for the old URL
  4. Users automatically fetch new version on next session

Alternatively, purge Cloudflare cache without filename change—browsers will re-fetch on next session.

Loading Screen UX: Making Wait Times Feel Instant

While optimizing bandwidth, we noticed that 50% of traffic comes from iframe embeds on community sites like EveDataCo.re. These embeds (often 640×360 pixels) had a poor loading experience:

Responsive Logo Sizing

We added embed-specific styling:

// Full app: 600px logo
const logoSize = embedMode ? 200 : 600;

<img 
  src="/logo.svg" 
  style={{
    width: `${logoSize}px`,
    height: `${logoSize}px`,
    aspectRatio: '1',        // Force square
    objectFit: 'contain'     // Preserve proportions
  }}
/>
Aspect Ratio Lock

The critical fix was adding aspect-ratio: 1 and removing max-height constraints. This prevents vertical squashing in small iframes while maintaining perfect logo proportions.

Theme-Aware Glow Effect

We detect cinematic color from URL parameters and apply it to the loading screen glow:

// Parse ?color=green from URL
const cinematicColor = new URLSearchParams(location.search).get('color');

// Map to theme accent
const glowColor = {
  'green': '#34a853',
  'blue': '#8ab4f8',
  'red': '#ea4335',
  'yellow': '#fbbc04',
  'orange': '#ff6d00'
}[cinematicColor] || '#8ab4f8';

// Apply glow
boxShadow: `0 0 60px ${glowColor}`

This creates visual continuity—users never see a jarring color shift from loading screen to loaded app.

Background Color Consistency

We changed the loading screen background from grey (#1a1a1a) to match the app's theme black (#0b0f17). Combined with early theme application via localStorage, users experience seamless visual flow.

Embed improvements:
  • Logo maintains square aspect ratio at all sizes
  • Glow color matches cinematic mode (no orange flash)
  • Background color consistent with embedded site
  • 200px logo loads instantly (1.23 KB SVG)

Race Condition Fix: The Orange Flash Bug

During embed testing, we discovered a subtle bug: users with ?color=green would see a brief orange flash as the page loaded, then the correct green theme would apply.

Root Cause

Two competing useEffect hooks:

// LoadingScreen.tsx: Set glow to green
useEffect(() => {
  document.documentElement.style.setProperty('--glow-color', green);
}, []);

// App.tsx: Restore saved orange theme from localStorage
useEffect(() => {
  const savedTheme = localStorage.getItem('theme'); // 'orange'
  document.documentElement.style.setProperty('--glow-color', savedTheme);
}, []);

The App.tsx effect ran after LoadingScreen mounted, overwriting the URL-specified color.

The Fix: isLoaded Guard

// App.tsx: Only restore theme AFTER loading completes
useEffect(() => {
  if (!isLoaded) return; // Guard against premature execution
  
  const savedTheme = localStorage.getItem('theme');
  document.documentElement.style.setProperty('--glow-color', savedTheme);
}, [isLoaded]); // Depend on loading state
Result: Green glow persists throughout loading; no color flash. Embed experience feels polished and intentional.

Measuring Impact

After all optimizations, here's the bandwidth breakdown:

Before Optimization

After Optimization

CDN Egress Cost Savings

With ~1,000 daily users and average 3 sessions per user:

  • Before: 1,000 × 3 × 6 MB = 18 GB/day = 540 GB/month
  • After: (1,000 × 73 MB) + (2,000 × 0.8 MB) = 74.6 GB/month
  • Reduction: 86% less egress
  • Cost impact: £12-22/month → £1-2/month (Cloudflare R2 pricing)

Key Takeaways

1. Vector > Raster for Logos

If your logo is geometric or illustrative (not photographic), convert it to SVG. The bandwidth savings are enormous, and resolution-independence is a bonus.

2. Cache Everything That's Stable

Universe data that changes once per 90-day cycle should never be fetched multiple times per user. Use IndexedDB for persistent client-side storage and aggressive HTTP caching for CDN efficiency.

3. Loading Screens Are UX, Not Just Placeholders

Users judge your app during the first 500ms of loading. Match colors, respect aspect ratios, and eliminate jarring transitions.

4. Embed Mode Deserves First-Class Treatment

If 50% of your traffic comes from iframes, optimize for that experience. Responsive sizing, theme detection, and visual consistency matter.

5. Race Conditions Hide in useEffect Chains

When multiple components modify global state (DOM styles, localStorage), add guards (isLoaded, isMounted) to prevent timing conflicts.

What's Next?

Bandwidth optimization is an ongoing process. Future improvements:

But for now, we've achieved the core goal: fast, efficient, and polished loading experience for all users.

Try It Yourself

Visit EVE Frontier Map on a fresh browser profile and watch the console logs—you'll see IndexedDB cache hits on your second session. Or embed the map with ?color=green to see the theme-aware loading screen in action.

← Back to Blog Try EVE Frontier Map →