Skip to content

Commit 309fc60

Browse files
committed
Implement multiple performance and UI improvements
1 parent fff45a5 commit 309fc60

14 files changed

Lines changed: 1654 additions & 803 deletions

index.html

Lines changed: 32 additions & 640 deletions
Large diffs are not rendered by default.

manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"start_url": "./",
66
"display": "standalone",
77
"background_color": "#ffffff",
8-
"theme_color": "#4a90e2",
8+
"theme_color": "#2563eb",
99
"orientation": "any",
1010
"scope": "./",
1111
"icons": [

service-worker.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ const STATIC_ASSETS = [
3535
'./src/js/utils.js',
3636
'./src/js/performance.js',
3737
'./src/js/pdf-generator.js',
38-
'./src/js/logger.js',
3938
'./src/js/error-handler.js',
4039
'./src/js/modals-content.js',
4140
'./src/js/inline-handlers.js'

src/js/config.js

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ export const MARKER_CONFIG = {
3838

3939
// Severity colors
4040
export const SEVERITY_COLORS = {
41-
'1: PDO': '#4a90e2',
41+
'1: PDO': '#2563eb', // Updated to match theme color
4242
'2: MI': '#f39c12',
4343
'3: SI': '#e67e22',
4444
'4: Fatal': '#e74c3c'
@@ -60,15 +60,16 @@ export const HEAVY_VEHICLE_TYPES = [
6060
];
6161

6262
// Tutorial tabs
63-
export const TUTORIAL_TABS = ['getting-started', 'filtering', 'analytics', 'tools', 'tips'];
63+
export const TUTORIAL_TABS = ['getting-started', 'filtering', 'analytics', 'tools', 'tips', 'quick-ref'];
6464

6565
// Tutorial tab content mapping
6666
export const TUTORIAL_TAB_CONTENT_MAP = {
6767
'getting-started': 'gettingStartedTab',
6868
'filtering': 'filteringTab',
6969
'analytics': 'analyticsTab',
7070
'tools': 'toolsTab',
71-
'tips': 'tipsTab'
71+
'tips': 'tipsTab',
72+
'quick-ref': 'quickRefTab'
7273
};
7374

7475
// Filter presets
@@ -258,7 +259,9 @@ export const MAP_CONFIG = {
258259
// Cache configuration
259260
export const CACHE_CONFIG = {
260261
MARKER_ICON_CACHE_SIZE: 1000,
261-
POPUP_CACHE_SIZE: 2000
262+
POPUP_CACHE_SIZE: 2000,
263+
FILTER_CACHE_SIZE: 50, // LRU cache size for filter results
264+
FILTER_CACHE_MAX_AGE: 7 * 24 * 60 * 60 * 1000 // 7 days in milliseconds
262265
};
263266

264267
// Loading configuration
@@ -268,8 +271,26 @@ export const LOADING_CONFIG = {
268271
URL_LOAD_DELAY: 2000
269272
};
270273

274+
// Performance timeouts (milliseconds)
275+
export const TIMEOUTS = {
276+
DEBOUNCE_DEFAULT: 300,
277+
THROTTLE_DEFAULT: 300,
278+
NOTIFICATION_DURATION: 5000,
279+
NOTIFICATION_FADE: 10000,
280+
CHART_RENDER_DELAY: 300,
281+
IDLE_CHUNK_SIZE: 100
282+
};
283+
271284
// Coordinate system configuration
272285
export const COORDINATE_SYSTEMS = {
273286
SOURCE: 'EPSG:3107', // GDA2020 / SA Lambert
274287
TARGET: 'EPSG:4326' // WGS84
275288
};
289+
290+
// South Australia coordinate boundaries for validation
291+
export const SA_BOUNDS = {
292+
LAT_MIN: -39,
293+
LAT_MAX: -25,
294+
LNG_MIN: 128,
295+
LNG_MAX: 142
296+
};

src/js/data-loader.js

Lines changed: 81 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -64,27 +64,16 @@ export function linkCrashData() {
6464
}
6565

6666
/**
67-
* Load units data with caching
67+
* Load units data with caching (standalone version for parallel loading)
6868
*/
69-
export async function loadUnitsData() {
70-
showLoading('Loading units data...');
71-
69+
async function loadUnitsDataOnly() {
7270
try {
7371
// Try cache first
7472
const cached = await dbCache.getFresh('crashData', 'units-2012-2024', 7 * 24 * 60 * 60 * 1000);
7573

7674
if (cached) {
7775
console.log('✅ Using cached units data');
7876
updateDataState({ unitsData: cached });
79-
linkCrashData();
80-
81-
const { populateFilterOptions } = await import('./filters.js');
82-
const { updateMarkerColorLegend } = await import('./map-renderer.js');
83-
84-
populateFilterOptions();
85-
updateMarkerColorLegend();
86-
await loadLGABoundaries();
87-
8877
return cached;
8978
}
9079

@@ -106,6 +95,24 @@ export async function loadUnitsData() {
10695
console.warn('Failed to cache units data:', cacheError);
10796
}
10897

98+
return unitsData;
99+
100+
} catch (error) {
101+
console.error('Error loading units data:', error);
102+
throw error;
103+
}
104+
}
105+
106+
/**
107+
* Load units data with caching (legacy - kept for compatibility)
108+
* @deprecated Use loadData() instead for parallel loading
109+
*/
110+
export async function loadUnitsData() {
111+
showLoading('Loading units data...');
112+
113+
try {
114+
const unitsData = await loadUnitsDataOnly();
115+
109116
// Link data together
110117
linkCrashData();
111118

@@ -122,27 +129,23 @@ export async function loadUnitsData() {
122129
return unitsData;
123130

124131
} catch (error) {
125-
console.error('Error loading units data:', error);
126132
hideLoading();
127133
alert('Error loading units data. Please check your connection and try again.');
128134
throw error;
129135
}
130136
}
131137

132138
/**
133-
* Load casualty data with caching
139+
* Load casualty data with caching (standalone version for parallel loading)
134140
*/
135-
export async function loadCasualtyData() {
136-
showLoading('Loading casualty data...');
137-
141+
async function loadCasualtyDataOnly() {
138142
try {
139143
// Try cache first
140144
const cached = await dbCache.getFresh('crashData', 'casualty-2012-2024', 7 * 24 * 60 * 60 * 1000);
141145

142146
if (cached) {
143147
console.log('✅ Using cached casualty data');
144148
updateDataState({ casualtyData: cached });
145-
await loadUnitsData();
146149
return cached;
147150
}
148151

@@ -164,35 +167,43 @@ export async function loadCasualtyData() {
164167
console.warn('Failed to cache casualty data:', cacheError);
165168
}
166169

167-
// Load units data next
168-
await loadUnitsData();
169-
170170
return casualtyData;
171171

172172
} catch (error) {
173173
console.error('Error loading casualty data:', error);
174+
throw error;
175+
}
176+
}
177+
178+
/**
179+
* Load casualty data with caching (legacy - kept for compatibility)
180+
* @deprecated Use loadData() instead for parallel loading
181+
*/
182+
export async function loadCasualtyData() {
183+
showLoading('Loading casualty data...');
184+
185+
try {
186+
await loadCasualtyDataOnly();
187+
// Load units data next
188+
await loadUnitsData();
189+
} catch (error) {
174190
hideLoading();
175191
alert('Error loading casualty data. Please check your connection and try again.');
176192
throw error;
177193
}
178194
}
179195

180196
/**
181-
* Load and decompress crash data with caching
197+
* Load and decompress crash data with caching (standalone version for parallel loading)
182198
*/
183-
export async function loadCrashData() {
184-
showLoading('Loading crash data...');
185-
199+
async function loadCrashDataOnly() {
186200
try {
187201
// Try to load from IndexedDB cache first
188202
const cached = await dbCache.getFresh('crashData', 'crash-2012-2024', 7 * 24 * 60 * 60 * 1000); // 7 days
189203

190204
if (cached) {
191205
console.log('✅ Using cached crash data');
192206
updateDataState({ crashData: cached });
193-
194-
// Load casualty data next
195-
await loadCasualtyData();
196207
return cached;
197208
}
198209

@@ -231,13 +242,26 @@ export async function loadCrashData() {
231242
// Non-fatal, continue anyway
232243
}
233244

234-
// Load casualty data next
235-
await loadCasualtyData();
236-
237245
return crashData;
238246

239247
} catch (error) {
240248
console.error('Error loading crash data:', error);
249+
throw error;
250+
}
251+
}
252+
253+
/**
254+
* Load and decompress crash data with caching (legacy - kept for compatibility)
255+
* @deprecated Use loadData() instead for parallel loading
256+
*/
257+
export async function loadCrashData() {
258+
showLoading('Loading crash data...');
259+
260+
try {
261+
await loadCrashDataOnly();
262+
// Load casualty data next
263+
await loadCasualtyData();
264+
} catch (error) {
241265
hideLoading();
242266
alert('Error loading crash data. Please check your connection and try again.');
243267
throw error;
@@ -364,12 +388,34 @@ export function precomputeLGAAssignments() {
364388
}
365389

366390
/**
367-
* Main data loading function
391+
* Main data loading function - parallelized for faster loading
368392
*/
369393
export async function loadData() {
370394
try {
371-
await loadCrashData();
372-
// Casualty and units data are loaded in sequence by loadCrashData
395+
// Load all three datasets in parallel for faster performance
396+
showLoading('Loading crash data (1/3)...');
397+
398+
const [crashDataResult, casualtyDataResult, unitsDataResult] = await Promise.all([
399+
loadCrashDataOnly(),
400+
loadCasualtyDataOnly(),
401+
loadUnitsDataOnly()
402+
]);
403+
404+
console.log('✅ All datasets loaded in parallel');
405+
406+
// Link data together after all loaded
407+
linkCrashData();
408+
409+
// After linking, populate filter options and load boundaries
410+
const { populateFilterOptions } = await import('./filters.js');
411+
const { updateMarkerColorLegend } = await import('./map-renderer.js');
412+
413+
populateFilterOptions();
414+
updateMarkerColorLegend();
415+
416+
// Load LGA boundaries (which will trigger initial filter application)
417+
await loadLGABoundaries();
418+
373419
} catch (error) {
374420
console.error('Failed to load data:', error);
375421
}

src/js/error-handler.js

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
* Provides centralised error handling and recovery mechanisms
44
*/
55

6-
import { logger } from './logger.js';
76
import { showNotification } from './ui.js';
87

98
/**
@@ -35,14 +34,14 @@ class ErrorHandler {
3534
setupGlobalHandlers() {
3635
// Handle unhandled promise rejections
3736
window.addEventListener('unhandledrejection', (event) => {
38-
logger.error('Unhandled promise rejection:', event.reason);
37+
console.error('Unhandled promise rejection:', event.reason);
3938
this.handleError(event.reason, ERROR_TYPES.UNKNOWN, 'Unhandled Promise');
4039
event.preventDefault();
4140
});
4241

4342
// Handle global errors
4443
window.addEventListener('error', (event) => {
45-
logger.error('Global error:', event.error || event.message);
44+
console.error('Global error:', event.error || event.message);
4645
this.handleError(
4746
event.error || new Error(event.message),
4847
ERROR_TYPES.UNKNOWN,
@@ -74,7 +73,7 @@ class ErrorHandler {
7473
}
7574

7675
// Log error
77-
logger.error(`[${type}] ${context}:`, error);
76+
console.error(`[${type}] ${context}:`, error);
7877

7978
// Show user notification if needed
8079
if (showUser) {

0 commit comments

Comments
 (0)