Ada Lovelace
Principal engineer · enjoys skeletons that never shift the layout.
Smonta il motore fase per fase. Per ogni passaggio ottieni il codice reale che gira, il DOM prima e dopo, lo stato del motore e il costo — come se lo stessi debuggando dal vivo.
<Skeletonizer :enabled="true">
<UserProfile />
</Skeletonizer>Principal engineer · enjoys skeletons that never shift the layout.
Scansione dal vivo
Acquisizione · passaggio 1
Al mount, l’host prende il proprio sottoalbero renderizzato: sarà il contenitore posizionato dell’overlay SVG.
Ogni <Skeletonizer> renderizza un elemento wrapper (che diventa position:relative quando attivo, così può ospitare l’overlay assoluto) e ne tiene un ref. Al mount registra un controller nello store globale e chiama store.engine.renderHost(root, meta). Il DOM reale prodotto dal tuo componente è l’input del motore — non c’è copia virtuale, e il sorgente non viene mai mutato.
components/Skeletonizer.vue
const root = ref<HTMLElement | null>(null)
onMounted(() => {
if (!root.value || !store) return
controller = { id: store._nextId(), scan: doScan, restore, report }
store._register(controller)
if (active.value) nextTick(() => doScan()) // doScan() → store.engine.renderHost(root.value, meta)
})mount
collega il motore, registra l’host
enable
nextTick → render
render
scan → SVG → inietta overlay
observe
MutationObserver con debounce
mutate
ri-render fuso (cache-aware)
disable
rimuovi overlay + ripristina
unmount
ripristina + deregistra
┌─────────────────────────┐
│ enable / DOM mutation │
└────────────┬────────────┘
▼
fingerprint(route, viewport, uid)
▼
blueprint cached? ── yes ─► replay SvgBlueprint (cache hit)
│ no │
▼ │
┌──────────────────┐ │
│ pop element │◄──────────┐ │
│ from DFS stack │ │ │
└────────┬─────────┘ │ │
▼ │ │
getComputedStyle(el) │ │
▼ │ │
┌─────────────┐ │ │
│ classify() │ │ │
└──┬───┬───┬──┘ │ │
skip ◄────────┘ │ └──► shimmer node │ │
│ ▼ │ │
ignored++ ┌────────────────┐ │ │
│ container? │── yes ─► push children ─┘ │
└───────┬────────┘ │
│ no (leaf) │
▼ │
measure → push ScannedNode { kind, rect, radius } │
▼ │
SvgRenderer → one <svg> + shared gradient │
▼ │
CLS guard: clamp viewBox → inject overlay ◄──────┘
▼
report { bones, ignored, timings, blueprint } → store._recompute()Tutto quanto sopra confluisce in un solo backend di rendering: SVG. L’host passa per lo SkeletonEngine — una pipeline modulare (Scan → SVG Renderer → CLS Guard → Iniezione DOM) che adatta l’animazione shimmer e il tier al carico reale del dispositivo, così l’interfaccia resta fluida anche su pagine di scala enterprise. È completamente additivo: con la configurazione predefinita l’overhead extra è zero.
1 · Scan Layer
misura il sottoalbero → ScannedNode[]
2 · SVG Renderer
un overlay <svg> + gradiente condiviso
3 · CLS Guard
blocca il viewBox al bounding box host
4 · Iniezione DOM
overlay assoluto, contenuto nascosto sul posto
5 · Telemetria
metriche + cache + feedback Explain
Principal engineer · enjoys skeletons that never shift the layout.
Segnali adattivi dal vivo
Misurazione in sola lettura
Percorre il sottoalbero e misura ogni foglia in un ScannedNode (tipo, DOMRect, raggio) — il DOM sorgente non viene mai mutato.
Qualsiasi densità
Mappa ScannedNode[] in un solo overlay <svg>: un <rect> per box, un <circle> per avatar — un elemento a prescindere dal numero di nodi.
Shimmer animato
Un solo <linearGradient> namespacato riusato da ogni forma, mosso da un singolo <animateTransform>.
Zero spostamento di layout
Blocca il viewBox al bounding box host e nasconde il contenuto reale sul posto — la pagina non si sposta mai.
Punteggio FPS/CPU, auto-degrado dell’animazione e disattivazione automatica dello shimmer, guidati da una policy a runtime che osserva i segnali dal vivo.
config.adaptive · minFps
L’unico backend di rendering: ScannedNode[] → un solo overlay <svg> (un <rect>/<circle> per nodo) con coordinate arrotondate.
config.renderMode · svgPrecision
Un solo <linearGradient> namespacato riusato da ogni forma, animato da un singolo sweep <animateTransform> — niente JS per nodo.
config.svgSharedGradient
Un fingerprint di layout hash(route + viewport + UID) mette in cache l’SvgBlueprint in memoria o sessione; un hit lo ripropone e salta la scansione.
config.layoutCache
Il microcontroller degrada wave → pulse → static sotto carico; il CLS guard blocca il viewBox così l’overlay è stabile al pixel.
tiers · cls-guard
Tempi per fase, FPS, memoria, cache ratio — con i calcoli pesanti (fingerprint, analisi) spostati su un Web Worker / requestIdleCallback.
config.telemetry · offThread
Blueprint Inspector (l’SVG generato), modalità Explain (decisioni in linguaggio naturale) e una classifica dei colli di bottiglia degli host più lenti.
useSkeletonPerformance()
Un motore modulare: Scan → SVG Renderer → CLS Guard → Iniezione DOM, dove ogni livello è disaccoppiato e testabile singolarmente.
SkeletonEngine