Contributo Umbraco 13: migliorare il Media Picker con paginazione – come l’abbiamo fatto

Introduzione

Nel nostro lavoro quotidiano con Umbraco CMS ci siamo imbattuti in un problema fastidioso, presente fin dalla 10.x e mai risolto fino alla serie 13: il Media Picker caricava tutti gli elementi di una cartella, anche quando si trattava di centinaia o migliaia di file, causando rallentamenti e timeout.

Per dare una soluzione concreta alla community, abbiamo deciso di intervenire direttamente sul core.
Siamo partiti dall’issue #12364, aperta nel 2022 e rimasta senza fix per anni, abbiamo sviluppato una patch e l’abbiamo proposta come PR #20202.

Dopo un accurato processo di review con il team Umbraco, la nostra pull request è stata approvata e fusa: il fix sarà disponibile a partire da Umbraco 13.12. 🎉

Nota importante
La correzione interessa solo la serie 13.x (e versioni precedenti ancora supportate).
In Umbraco 14 e successivi il bug era già stato risolto nativamente nel core, quindi non serve applicare questa patch.


Sezione 1 — Il problema iniziale

Cosa succedeva
Quando si apriva il Media Picker in una cartella con molti file, l’interfaccia Angular richiamava un endpoint che restituiva tutti i figli senza paginazione.
Per cartelle con centinaia o migliaia di elementi questo significava:

  • query pesanti sul database,

  • grande consumo di RAM,

  • possibili timeout lato browser e lato server.

Perché permane su 13.x
La serie 14 ha introdotto un Media Picker rinnovato che risolve automaticamente questa inefficienza.
Ma la 13.x è una LTS ancora molto diffusa, quindi il problema rimaneva per tutti i progetti che non possono passare subito alla major successiva.

Riferimenti

  • Issue originale (aperta nel 2022): #12364

  • Pull request di fix: #20202


Sezione 2 — Analisi e proposta di soluzione

File analizzati

  • EntityController (back-office): endpoint GetChildren chiamato dal client.

  • mediapicker.controller.js (front-end Angular): implementa le chiamate a entityResource.getChildren(...).

Diagnosi
Il problema non era a livello server ma nel front-end: il Media Picker non passava mai parametri di paging (skip, take), caricando sempre tutto.

Scelte valutate

  1. Modifica lato server (limitare implicitamente i risultati): rischioso, potenziale breaking change.

  2. Uso degli endpoint già esistenti di paging (getPagedChildren) nel client: sicuro, retro-compatibile.

Soluzione adottata

  • Sostituzione di entityResource.getChildren(...) con entityResource.getPagedChildren(...), inviando pageNumber, pageSize e (solo se necessario) parametri di ordinamento.

  • Introduzione di logica di paginazione lato front-end: reset della pagina quando si cambia cartella, gestione coerente anche durante la ricerca.

  • Refactoring per ridurre la complessità ciclomatica: estratti piccoli helper, rimossi commenti temporanei, lasciati solo commenti tecnici chiari.


Sezione 3 — Il processo di review

Durante la review il team Umbraco, in particolare Andy Butland, ha svolto un lavoro molto accurato.
Alcuni punti chiave:

  • Parametri inutili
    In una versione intermedia avevamo aggiunto orderBy: "VersionDate" e orderDirection: "Descending".
    Su richiesta di Andy li abbiamo rimossi, dato che il paging funziona correttamente con l’ordinamento di default.

  • Commenti “da revisore”
    Alcune note come // MOD: o // helpers to reduce complexity sono state eliminate o sostituite con spiegazioni tecniche utili, ad esempio

    // reset filter to ensure folder navigation always starts unfiltered.

  • Promise e ritorni coerenti
    La vera soluzione è stata rendere coerente la catena di promise (run(), ensureWithinStartNode(), gotoStartNode(), gotoFolder()), per garantire che la chiamata getPagedChildren sia sempre eseguita anche quando il Media Picker riapre direttamente nell’ultima cartella visitata.

  • Formattazione
    Migliorata l’indentazione delle catene .then(...).finally(...) per maggiore leggibilità.

Grazie a questo confronto aperto, il codice finale è più solido, pulito e manutenibile.


Sezione 4 — Il risultato e i benefici per la community

  • Performance migliorata
    Ora il Media Picker carica solo gli elementi della pagina corrente (es. 100 o 200 alla volta), con un impatto enorme su tempi di caricamento e memoria.

  • Nessun breaking change
    Il back-end (EntityController) resta invariato: chi usa ancora getChildren non subisce alcun cambiamento.

  • Codice più chiaro
    La gestione della paginazione è leggibile e documentata, facilitando la manutenzione futura.

  • Valore per chi resta su Umbraco 13
    Le aziende che non possono migrare subito a 14 (o che sono ancora su 10–12) possono aggiornare tranquillamente a 13.12 e godere dei miglioramenti.


Sezione 5 — Cosa abbiamo imparato (e consigli pratici)

  • Anche i piccoli bug contano: un’ottimizzazione del backoffice può migliorare la vita quotidiana di molti editori di contenuti.

  • Dialogo costruttivo con i maintainer: ogni commento della review è stato un’occasione per semplificare e rafforzare il codice.

  • Scrivere meno ma meglio: rimuovere codice inutile è spesso il miglior fix.

  • Documentare il “perché”: spiegare le ragioni di un reset o di una scelta di design aiuta chi leggerà tra mesi o anni.


Conclusione e call to action

Siamo orgogliosi che la nostra PR #20202 sia stata accettata e inclusa ufficialmente nel core di Umbraco, a partire dalla versione 13.12.
Dopo quasi due anni dall’apertura dell’issue #12364, la community Umbraco ha finalmente una soluzione nativa e stabile.

Se utilizzi Umbraco 13.x (o versioni 10–12) e vuoi:

  • migliorare le performance del backoffice,

  • scrivere estensioni,

  • o ricevere supporto per migrazioni complesse,

contattaci su landlogic.it: saremo felici di condividere la nostra esperienza e contribuire al successo del tuo progetto.