perf: faster map boot — zoom-gate heavy layers, static basemap, defer HUD, lazy HLS
World view no longer fetches cameras/NWS/WFIGS. Default Blue Marble so init does not wait on GIBS times. News/summary/events load with their views. hls.min.js loads only on the first HLS camera popup.
This commit is contained in:
parent
dd7a09aadd
commit
07638288a9
1 changed files with 71 additions and 20 deletions
|
|
@ -1026,10 +1026,22 @@
|
|||
<script src="/static/vendor/leaflet/leaflet.js"></script>
|
||||
<script src="/static/vendor/leaflet/leaflet.markercluster.js"></script>
|
||||
<script src="/static/vendor/leaflet/leaflet.heat.js"></script>
|
||||
<script src="/static/vendor/hls/hls.min.js"></script>
|
||||
<script>
|
||||
const API = '';
|
||||
|
||||
function loadHls() {
|
||||
if (window.Hls) return Promise.resolve();
|
||||
if (window._hlsLoading) return window._hlsLoading;
|
||||
window._hlsLoading = new Promise((res, rej) => {
|
||||
const s = document.createElement('script');
|
||||
s.src = '/static/vendor/hls/hls.min.js';
|
||||
s.onload = res;
|
||||
s.onerror = rej;
|
||||
document.head.appendChild(s);
|
||||
});
|
||||
return window._hlsLoading;
|
||||
}
|
||||
|
||||
/* ═══════════════ BOOT SPLASH ═══════════════ */
|
||||
(function () {
|
||||
const boot = document.getElementById('boot');
|
||||
|
|
@ -1136,7 +1148,8 @@ function showView(name) {
|
|||
}
|
||||
}
|
||||
if (name === 'news') loadNews(false);
|
||||
if (name === 'settings') renderSysInfo();
|
||||
if (name === 'events') { loadSummary(); loadEvents(); }
|
||||
if (name === 'settings') { loadSummary(); renderSysInfo(); }
|
||||
window.scrollTo(0, 0);
|
||||
}
|
||||
|
||||
|
|
@ -1651,7 +1664,10 @@ async function initMap() {
|
|||
const sel = document.getElementById('map-layer');
|
||||
sel.innerHTML = mapLayers.map(l =>
|
||||
`<option value="${l.id}">${l.title}</option>`).join('');
|
||||
const preferred = mapLayers.find(l => l.has_time) || mapLayers[0];
|
||||
const preferred =
|
||||
mapLayers.find(l => l.id === 'BlueMarble_ShadedRelief_Bathymetry')
|
||||
|| mapLayers.find(l => !l.has_time)
|
||||
|| mapLayers[0];
|
||||
if (preferred) sel.value = preferred.id;
|
||||
map = L.map('map', {
|
||||
center: [25, 10], zoom: 2,
|
||||
|
|
@ -1676,6 +1692,7 @@ async function initMap() {
|
|||
img.alt = 'camera preview';
|
||||
v.replaceWith(img);
|
||||
};
|
||||
const startHls = () => {
|
||||
if (window.Hls && Hls.isSupported()) {
|
||||
activeHls = new Hls({ enableWorker: true, lowLatencyMode: true });
|
||||
activeHls.loadSource(v.dataset.hls);
|
||||
|
|
@ -1690,6 +1707,9 @@ async function initMap() {
|
|||
} else {
|
||||
fallback();
|
||||
}
|
||||
};
|
||||
if (window.Hls) startHls();
|
||||
else loadHls().then(startHls).catch(fallback);
|
||||
});
|
||||
map.on('popupclose', () => {
|
||||
if (activeHls) { try { activeHls.destroy(); } catch (_) {} activeHls = null; }
|
||||
|
|
@ -1719,7 +1739,8 @@ async function initMap() {
|
|||
refreshLiveOverlays();
|
||||
}, 300);
|
||||
});
|
||||
await mapLayerChanged();
|
||||
// Static Blue Marble has no time-domain fetch — don't block overlays on GIBS.
|
||||
mapLayerChanged();
|
||||
// Overlays default ON (checkboxes in the layer panel + saved settings)
|
||||
applyMapSettings(readMapPrefs(), false);
|
||||
firesOn = document.getElementById('lp-fires-on').checked;
|
||||
|
|
@ -2036,6 +2057,13 @@ function camThumb(c) {
|
|||
}
|
||||
async function loadCams() {
|
||||
if (!map) return;
|
||||
if (tooZoomedOut()) {
|
||||
camsGroup = dropLayer(camsGroup);
|
||||
markZoom('lp-cams-count');
|
||||
hudCamsCount = null;
|
||||
syncHud();
|
||||
return;
|
||||
}
|
||||
const req = ++camReq;
|
||||
try {
|
||||
const r = await fetch(`${API}/api/cameras?bbox=${currentBBox()}&limit=5000`);
|
||||
|
|
@ -2175,6 +2203,14 @@ function dropLayer(ref) {
|
|||
if (ref && map && map.hasLayer(ref)) map.removeLayer(ref);
|
||||
return null;
|
||||
}
|
||||
/* Polygon/camera layers hitch at world scale. Same idea as aircraft's zoom<=3
|
||||
skip: do not fetch or render these until the user is zoomed in. */
|
||||
const HEAVY_MIN_ZOOM = 4;
|
||||
function tooZoomedOut() { return !map || map.getZoom() <= HEAVY_MIN_ZOOM; }
|
||||
function markZoom(id) {
|
||||
const el = document.getElementById(id);
|
||||
if (el) el.textContent = 'zoom';
|
||||
}
|
||||
function intersectsConus() {
|
||||
if (!map) return false;
|
||||
const b = map.getBounds();
|
||||
|
|
@ -2338,6 +2374,11 @@ async function toggleWxAlerts() {
|
|||
}
|
||||
async function loadWxAlerts() {
|
||||
if (!map) return;
|
||||
if (tooZoomedOut()) {
|
||||
wxAlertsGroup = dropLayer(wxAlertsGroup);
|
||||
markZoom('lp-alerts-count');
|
||||
return;
|
||||
}
|
||||
const req = ++overlayReq.alerts;
|
||||
try {
|
||||
const r = await fetch(`${API}/api/weather-alerts?bbox=${currentBBox()}`);
|
||||
|
|
@ -2369,6 +2410,11 @@ async function togglePerimeters() {
|
|||
}
|
||||
async function loadPerimeters() {
|
||||
if (!map) return;
|
||||
if (tooZoomedOut()) {
|
||||
perimGroup = dropLayer(perimGroup);
|
||||
markZoom('lp-perim-count');
|
||||
return;
|
||||
}
|
||||
const req = ++overlayReq.perim;
|
||||
try {
|
||||
const r = await fetch(`${API}/api/fire-perimeters?bbox=${currentBBox()}`);
|
||||
|
|
@ -2402,6 +2448,11 @@ async function toggleIncidents() {
|
|||
}
|
||||
async function loadIncidents() {
|
||||
if (!map) return;
|
||||
if (tooZoomedOut()) {
|
||||
incidentsGroup = dropLayer(incidentsGroup);
|
||||
markZoom('lp-incidents-count');
|
||||
return;
|
||||
}
|
||||
const req = ++overlayReq.incidents;
|
||||
try {
|
||||
const r = await fetch(`${API}/api/fire-incidents?bbox=${currentBBox()}`);
|
||||
|
|
@ -2511,9 +2562,9 @@ async function loadStorms() {
|
|||
initNav();
|
||||
initSettings();
|
||||
initMarketTicker();
|
||||
loadSummary(); loadEvents(); loadNews(true); checkHealth();
|
||||
setInterval(() => { loadSummary(); loadEvents(); checkHealth(); }, 30000);
|
||||
checkHealth();
|
||||
initMap();
|
||||
setInterval(checkHealth, 30000);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue