Skeletonizzazione automatica

Come il motore di scansione del DOM classifica gli elementi e preserva il layout.

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 su width/height dell'SVG (arrotondate a svgPrecision cifre 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-radius calcolato dell'elemento si trasferisce direttamente su rx/ry della 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 artificiale 100% / 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 un avatar: 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-items e il gap riga/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() e getComputedStyle(). Il contenuto reale viene nascosto con visibility: 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 direttivev-skeleton-ignore, v-skeleton-keep, v-skeleton-replace, v-skeleton-union, v-skeleton-shimmer — per sovrascrivere il motore dove serve precisione.