Skeletonizzazione automatica
Skeletonizzazione automatica
Il cuore del modulo è un motore che analizza il DOM ed è in esecuzione dentro ogni
<Skeletonizer> attivo. Percorre il sottoalbero renderizzato (DFS con leaf-stop), misura ogni
elemento che skeletonizzerà, lo classifica e renderizza l'intero risultato come un unico overlay
<svg> posizionato sopra il contenuto reale (nascosto ma ancora presente nel layout) — senza mai
spostare, avvolgere o rimuovere un nodo.
Cosa riconosce
Il motore classifica gli elementi in tipi semantici di osso:
text · heading · image · avatar · badge · tag · button · icon · input ·
textarea · select · checkbox · radio · switch · oltre ai generici block / container e
ai componenti personalizzati.
La classificazione usa i nomi dei tag, i ruoli ARIA, gli stili calcolati e la struttura (ad es. un
elemento pressoché quadrato con raggio circolare diventa un avatar; un <img> diventa un image).
Fedeltà di layout — una replica strutturale, non un'approssimazione
Lo skeleton non è un sostituto approssimativo: viene misurato per essere una replica strutturalmente fedele del layout reale, coordinata per coordinata.
Elemento reale → Bounding box (scan) → Blueprint SVG → Skeleton renderizzato
312×48px { x, y, w:312, <rect width="312" box identico
rx 8px h:48, radius:8 } height="48" rx="8"/> 312×48
Cosa viene preservato esattamente, senza inventare alcun valore:
- Larghezza e altezza — lette tramite
getBoundingClientRect()e trasferite invariate suwidth/heightdell'SVG (arrotondate asvgPrecisioncifre decimali, così il blueprint corrisponde al box reale con una tolleranza di ±1px). Nessuna larghezza arbitraria, nessuna percentuale indovinata, nessun rimpicciolimento casuale. - Border radius — il
border-radiuscalcolato dell'elemento si trasferisce direttamente surx/rydella forma (oppure su un<circle>quando l'elemento è quadrato e visivamente rotondo — vedi Avatar più sotto). - Righe di testo — un nodo di testo che va a capo viene misurato riga per riga
(
Range.getClientRects()), quindi un paragrafo che si spezza in 3 righe reali da 320px / 287px / 164px produce esattamente 3 ossa da 320px / 287px / 164px. Il motore non ricade mai su una scala artificiale100% / 90% / 75%quando la larghezza reale di ogni riga è disponibile; solo quando non esiste alcuna informazione di layout testuale (ad es. una foglia vuota) ricade sul box dell'elemento stesso. - Immagini e avatar — un osso
<img>/<picture>/<video>mantiene larghezza, altezza e aspect ratio reali dell'elemento (mai deformato in un quadrato). Un elemento pressoché quadrato con un raggio visivamente circolare diventa unavatar: un vero<circle>quando risulta completamente rotondo, oppure un<rect rx>che rispecchia il raggio misurato quando è invece un quadrato con angoli arrotondati. - Struttura flex e grid — poiché ogni discendente viene disegnato nella propria posizione
assoluta reale (relativa all'host), una grid non collassa mai in una lista verticale e una riga
flex non collassa mai in una pila: i gap e gli allineamenti sono impliciti nelle coordinate
misurate. Lo strato di scansione registra inoltre, per ogni container flex/grid,
display,flex-direction/justify-content/align-itemse ilgapriga/colonna, a scopo di verifica e per DevTools/Explain — questi metadati sono una registrazione di ciò che il renderer riproduce già geometricamente, non un'approssimazione separata.
Il renderer è deterministico: gli stessi nodi scansionati producono sempre lo stesso markup SVG — nessuna lunghezza di riga casuale, nessuna variazione estetica.
Come viene dipinto un osso
- Lo strato di scansione non muta mai il sottoalbero reale — legge solo
getBoundingClientRect()egetComputedStyle(). Il contenuto reale viene nascosto convisibility: hidden(il suo box di layout resta al suo posto, ed è proprio questo a rendere possibile la misurazione). - Il renderer SVG trasforma i nodi misurati in un unico overlay
<svg>posizionato in assoluto: ogni osso è un<rect>(o un<circle>per avatar/radio), riempito da un<linearGradient>condiviso e namespacizzato che pilota lo shimmer per tutte le forme contemporaneamente. - Disattivare lo skeleton rimuove l'overlay e ripristina
visibility: visible— il markup reale non è mai stato toccato.
Riscansione
Un MutationObserver con debounce osserva il sottoalbero, così i contenuti aggiunti dopo la prima
scansione (liste lazy, componenti asincroni) vengono skeletonizzati automaticamente. Puoi anche
chiamare refresh() manualmente.
Mescolare con skeleton manuali
I componenti manuali Skeleton* vengono riconosciuti e lasciati intatti dal motore, così puoi
mescolare liberamente skeleton automatici e composti a mano nello stesso albero.
Pilotarlo
Usa le direttive — v-skeleton-ignore, v-skeleton-keep, v-skeleton-replace,
v-skeleton-union, v-skeleton-shimmer — per sovrascrivere il motore dove serve precisione.