50 lines
1.5 KiB
JavaScript
50 lines
1.5 KiB
JavaScript
/**
|
|
* Loader de partials HTML (menú + footer).
|
|
* - Usa fetch + cache del navegador.
|
|
* - Inyecta con innerHTML (sin reflow bloqueante).
|
|
* - Diferido con requestIdleCallback para no competir con el render.
|
|
*/
|
|
(function () {
|
|
'use strict';
|
|
|
|
const PARTIALS = [
|
|
{ url: 'partials/menu.html', target: 'menu-placeholder' },
|
|
{ url: 'partials/footer.html', target: 'footer-placeholder' }
|
|
];
|
|
|
|
// Cache en memoria para evitar refetch si se llama varias veces
|
|
const cache = new Map();
|
|
|
|
async function loadPartial({ url, target }) {
|
|
const el = document.getElementById(target);
|
|
if (!el) return;
|
|
|
|
try {
|
|
let html = cache.get(url);
|
|
if (!html) {
|
|
const res = await fetch(url, { cache: 'force-cache' });
|
|
if (!res.ok) throw new Error(`HTTP ${res.status} en ${url}`);
|
|
html = await res.text();
|
|
cache.set(url, html);
|
|
}
|
|
// Inserción vía fragmento para minimizar reflows
|
|
el.outerHTML = html;
|
|
} catch (err) {
|
|
console.warn(`[loader] No se pudo cargar ${url}:`, err);
|
|
// Fallback silencioso: deja el placeholder vacío
|
|
}
|
|
}
|
|
|
|
function loadAll() {
|
|
// En paralelo: ambas peticiones viajan juntas
|
|
PARTIALS.forEach(loadPartial);
|
|
}
|
|
|
|
// Espera al idle para no bloquear LCP/FCP
|
|
if ('requestIdleCallback' in window) {
|
|
requestIdleCallback(loadAll, { timeout: 1500 });
|
|
} else {
|
|
// Fallback para Safari
|
|
window.addEventListener('load', () => setTimeout(loadAll, 0));
|
|
}
|
|
})(); |