Creo applicazioni web moderne e strumenti digitali personalizzati per aiutare le attività a crescere attraverso l'innovazione tecnologica. La mia passione è unire informatica ed economia per generare valore reale.
La mia passione per l'informatica è nata tra i banchi dell'Istituto Tecnico Commerciale di Maglie, dove ho scoperto il potere della programmazione e il fascino di creare soluzioni digitali. Fin da subito, ho capito che l'informatica non era solo codice, ma uno strumento straordinario per trasformare idee in realtà.
Durante gli studi superiori in Sistemi Informativi Aziendali, ho iniziato a intrecciare informatica ed economia, comprendendo come la tecnologia possa essere il motore della crescita per qualsiasi attività. Questa visione mi ha accompagnato all'Università degli Studi di Bari, dove ho conseguito la Laurea in Informatica, approfondendo le mie competenze tecniche e la mia passione per lo sviluppo software.
Oggi metto questa esperienza al servizio di imprese, professionisti e startup, creando soluzioni digitali su misura che automatizzano processi, ottimizzano risorse e aprono nuove opportunità di business. Perché la vera innovazione inizia quando la tecnologia incontra le esigenze reali delle persone.
Le Mie Competenze
Analisi Dati & Modelli Previsionali
Trasformo i dati in insights strategici con analisi approfondite e modelli predittivi per decisioni informate
Automazione Processi
Creo strumenti personalizzati che automatizzano operazioni ripetitive e liberano tempo per attività a valore aggiunto
Sistemi Custom
Sviluppo sistemi software su misura, dalle integrazioni tra piattaforme alle dashboard personalizzate
Credo fermamente che l'informatica sia lo strumento più potente per trasformare le idee in realtà e migliorare la vita delle persone.
🚀
Democratizzare la Tecnologia
La mia missione è rendere l'informatica accessibile a tutti: dalle piccole imprese locali alle startup innovative, fino ai professionisti che vogliono digitalizzare la propria attività. Ogni realtà merita di sfruttare le potenzialità del digitale.
💡
Unire Informatica ed Economia
Non è solo questione di scrivere codice: è capire come la tecnologia possa generare valore reale. Intrecciando competenze informatiche e visione economica, aiuto le attività a crescere, ottimizzare processi e raggiungere nuovi traguardi di efficienza e redditività.
🎯
Creare Soluzioni su Misura
Ogni attività è unica, e così devono esserlo le soluzioni. Sviluppo strumenti personalizzati che rispondono alle esigenze specifiche di ciascun cliente, automatizzando processi ripetitivi e liberando tempo per ciò che conta davvero: far crescere il business.
Trasforma la Tua Attività con la Tecnologia
Che tu gestisca un negozio, uno studio professionale o un'azienda, posso aiutarti a sfruttare le potenzialità dell'informatica per lavorare meglio, più velocemente e in modo più intelligente.
Il mio percorso accademico e le tecnologie che padroneggio
Certificazioni Professionali
8 certificazioni conseguite
Nuovo
Visualizza
Reinvention With Agentic AI Learning Program
Anthropic
Dicembre 2024
Nuovo
Visualizza
Agentic AI Fluency
Anthropic
Dicembre 2024
Nuovo
Visualizza
AI Fluency for Students
Anthropic
Dicembre 2024
Nuovo
Visualizza
AI Fluency: Framework and Foundations
Anthropic
Dicembre 2024
Nuovo
Visualizza
Claude with the Anthropic API
Anthropic
Dicembre 2024
Visualizza
Master SQL
RoadMap.sh
Novembre 2024
Visualizza
Oracle Certified Foundations Associate
Oracle
Ottobre 2024
Visualizza
People Leadership Credential
Connect
Settembre 2024
💻 Linguaggi & Tecnologie
☕Java
🐍Python
📜JavaScript
🅰️Angular
⚛️React
🔷TypeScript
🗄️SQL
🐘PHP
🎨CSS/SCSS
🔧Node.js
🐳Docker
🌿Git
💼
12/2024 - Presente
Custom Software Engineering Analyst
Accenture
Bari, Puglia, Italia · Ibrida
Analisi e sviluppo di sistemi informatici attraverso l'utilizzo di Java e Quarkus in Health and Public Sector. Formazione continua su tecnologie moderne per la creazione di soluzioni software personalizzate ed efficienti e sugli agenti.
💼
06/2022 - 12/2024
Analista software e Back End Developer Associate Consultant
Links Management and Technology SpA
Esperienza nell'analisi di sistemi software as-is e flussi ETL utilizzando PowerCenter. Formazione completata su Spring Boot per lo sviluppo di applicazioni backend moderne e scalabili. Sviluppatore Backend specializzato in Spring Boot, con esperienza in progettazione di database, analisi, sviluppo e testing dei task assegnati.
💼
02/2021 - 10/2021
Programmatore software
Adesso.it (prima era WebScience srl)
Esperienza nell'analisi AS-IS e TO-BE, evoluzioni SEO ed evoluzioni website per migliorare le performance e l'engagement degli utenti.
🎓
2018 - 2025
Laurea in Informatica
Università degli Studi di Bari Aldo Moro
Bachelor's degree in Computer Science, focusing on software engineering, algorithms, and modern development practices.
📚
2013 - 2018
Diploma - Sistemi Informativi Aziendali
Istituto Tecnico Commerciale di Maglie
Technical diploma specializing in Business Information Systems, combining IT knowledge with business management.
Contattami
Hai un progetto in mente? Parliamone! Compila il form qui sotto e ti risponderò al più presto.
* Campi obbligatori. I tuoi dati saranno utilizzati solo per rispondere alla tua richiesta.
scheduler.yield() e Long Tasks: Sblocca il Main Thread
Il browser ha un solo main thread. Su questo thread girano, in sequenza, tutto il JavaScript della
tua applicazione, il layout e il paint della pagina, e la risposta agli input dell'utente. Il modello
di esecuzione di JavaScript e run-to-completion: un task JavaScript, una volta iniziato,
viene eseguito fino alla fine senza interruzioni. Se quel task richiede 300ms, per quei 300ms il
browser non puo fare nient'altro: non risponde ai click, non aggiorna l'interfaccia, non processa
altri eventi.
Questo e il problema fondamentale che causa INP elevato. La soluzione tradizionale era usare
setTimeout(fn, 0) o Promise.resolve().then() per "dividere" il lavoro,
ma questi approcci hanno problemi di prioritizzazione e non comunicano al browser l'intenzione
di cedere il controllo. scheduler.yield() e la soluzione nativa
progettata esplicitamente per questo scopo.
Cosa Imparerai
Come funziona il main thread e il modello run-to-completion di JavaScript
Cosa sono i Long Tasks e come identificarli con Chrome DevTools
Come scheduler.yield() differisce da setTimeout e Promise.resolve()
Pattern pratici per spezzare task pesanti preservando la priorita
scheduler.postTask() per task con priorita esplicita
Come misurare il miglioramento INP dopo le ottimizzazioni
Il Problema: Run-to-Completion e Long Tasks
Immagina di avere un event handler che, al click di un bottone, deve processare un array di 10.000
elementi e aggiornare il DOM. Senza ottimizzazioni:
// PROBLEMA: questo handler blocca il main thread per centinaia di ms
document.getElementById('process-btn').addEventListener('click', () => {
const results = [];
// Elaborazione sincrona di 10.000 elementi
for (const item of largeDataset) {
results.push(expensiveTransform(item)); // ogni chiamata costa ~0.1ms
}
// Aggiornamento DOM con tutti i risultati
renderResults(results);
});
Questo handler esegue in modo sincrono per ~1000ms (10.000 item * 0.1ms). Durante quell'intero
secondo, il browser non puo rispondere ad altri input, non puo aggiornare l'animazione di un
loading spinner, e non puo processare altri eventi. L'INP per questa interazione sara > 1000ms.
Visualizzare il Problema con Performance Observer
// Monitora i Long Tasks in produzione
const observer = new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
if (entry.duration > 50) {
console.warn(`Long Task:
scheduler.yield() e una nuova API del Scheduler browser (Baseline 2024, 87% supporto
browser) che permette a un task JavaScript di cedere il controllo al browser in modo controllato.
Il task puo poi riprendersi dove si era fermato, con la garanzia che il browser abbia avuto
la possibilita di processare eventi pendenti.
Ecco come riscrivere l'esempio precedente con scheduler.yield():
document.getElementById('process-btn').addEventListener('click', async () => {
const results = [];
const CHUNK_SIZE = 100; // processa 100 elementi per volta
for (let i = 0; i < largeDataset.length; i += CHUNK_SIZE) {
// Processa un chunk di elementi
const chunk = largeDataset.slice(i, i + CHUNK_SIZE);
for (const item of chunk) {
results.push(expensiveTransform(item));
}
// Cedi il controllo al browser tra un chunk e l'altro
// Il browser puo ora processare input pendenti, animazioni, ecc.
await scheduler.yield();
}
// Aggiorna il DOM con i risultati finali
renderResults(results);
});
Con questo pattern, invece di un unico Long Task da 1000ms, abbiamo 100 task da 10ms ciascuno,
con "yield points" tra uno e l'altro. Il browser puo rispondere agli input tra un chunk e l'altro,
portando l'INP da > 1000ms a < 50ms per la risposta iniziale.
scheduler.yield() vs setTimeout(0) vs Promise.resolve()
La differenza fondamentale tra scheduler.yield() e le tecniche precedenti sta
nella prioritizzazione:
Metodo
Priorita
Comportamento
Problema
setTimeout(fn, 0)
Bassa
Aggiunge alla coda dei macrotask
Minimo 4ms di delay, priorita imprevedibile
Promise.resolve()
Alta (microtask)
Esegue prima di altri task
Non cede realmente il controllo al browser
scheduler.yield()
Eredita dal task chiamante
Cede controllo, mantiene priorita originale
Nessuno (tranne il supporto browser del 87%)
Il punto chiave di scheduler.yield() e che mantiene la priorita del task chiamante.
Se l'utente ha appena cliccato un bottone (alta priorita), i chunk successivi avranno ancora
alta priorita rispetto ad altri task di background. Con setTimeout(0), i chunk
verrebbero degradati a priorita bassa, potendo essere superati da altri task.
scheduler.postTask(): Controllo Completo della Priorita
Per scenari piu avanzati, scheduler.postTask() permette di pianificare task con
priorita esplicita: 'user-blocking' (critica, es. risposta a input utente),
'user-visible' (importante, es. rendering di contenuto), e 'background'
(non urgente, es. analytics, prefetch).
Puoi anche cancellare task pendenti tramite TaskController:
const controller = new TaskController({ priority: 'user-visible' });
// Avvia il task
const taskPromise = scheduler.postTask(
() => { doWork(); },
{ signal: controller.signal }
);
// Cancella il task se l'utente naviga via
window.addEventListener('beforeunload', () => {
controller.abort();
});
Pattern Pratici per Framework JavaScript
React: Splitting del Rendering Pesante
function HeavyList({ items }: { items: Item[] }) {
const [visibleItems, setVisibleItems] = useState<Item[]>([]);
useEffect(() => {
const renderChunks = async () => {
const CHUNK_SIZE = 50;
const allItems: Item[] = [];
for (let i = 0; i < items.length; i += CHUNK_SIZE) {
const chunk = items.slice(i, i + CHUNK_SIZE);
allItems.push(...chunk);
// Aggiorna lo stato con il chunk corrente
setVisibleItems([...allItems]);
// Cedi il controllo prima del prossimo chunk
if ('scheduler' in window && 'yield' in scheduler) {
await scheduler.yield();
} else {
// Fallback per browser non supportati
await new Promise(resolve => setTimeout(resolve, 0));
}
}
};
renderChunks();
}, [items]);
return <ul>{visibleItems.map(item => <li key={item.id}>{item.name}</li>)}</ul>;
}
Angular: Heavy Computation in OnInit
@Component({
selector: 'app-data-table',
template: `<div *ngFor="let row of processedRows">{{ row.value }}</div>`
})
export class DataTableComponent implements OnInit {
processedRows: ProcessedRow[] = [];
constructor(private ngZone: NgZone) {}
async ngOnInit() {
// Esegui fuori da Angular zone per evitare change detection
// ad ogni yield
await this.ngZone.runOutsideAngular(async () => {
const CHUNK_SIZE = 100;
const results: ProcessedRow[] = [];
for (let i = 0; i < this.rawData.length; i += CHUNK_SIZE) {
const chunk = this.rawData.slice(i, i + CHUNK_SIZE);
results.push(...chunk.map(r => this.processRow(r)));
if ('scheduler' in window) {
await (window as any).scheduler.yield();
}
}
// Rientra in Angular zone solo per l'aggiornamento finale
this.ngZone.run(() => {
this.processedRows = results;
});
});
}
}
Come Verificare il Miglioramento
Dopo aver implementato scheduler.yield(), verifica il miglioramento INP:
Chrome DevTools Performance Panel: registra la stessa interazione prima e dopo
l'ottimizzazione. Dovresti vedere molti task brevi invece di uno lungo.
web-vitals.js in produzione: monitora il P75 dell'INP per alcuni giorni dopo
il deploy. Un miglioramento tipico e dal 40% al 70% del valore INP.
Interaction to Next Paint trace: nel Performance panel, l'input delay dovrebbe
ridursi significativamente, poiche i Long Tasks non bloccano piu il main thread al momento del click.
Supporto Browser e Fallback
scheduler.yield() e supportato da Chrome 115+, Edge 115+, Safari 17+ (87% degli utenti).
Per Firefox e browser piu vecchi, usa il fallback new Promise(resolve => setTimeout(resolve, 0)).
Crea un'utility function che astrae la differenza:
async function yieldToMain(): Promise<void> {
if ('scheduler' in window && 'yield' in (window as any).scheduler) {
return (window as any).scheduler.yield();
}
return new Promise(resolve => setTimeout(resolve, 0));
}
Conclusioni
scheduler.yield() e lo strumento piu potente disponibile oggi per migliorare INP
su interfacce JavaScript complesse. La tecnica di spezzare i task pesanti in chunk con yield points
intermedi e concettualmente semplice ma ha un impatto enorme sull'esperienza utente percepita.
La chiave e identificare prima le interazioni problematiche con Chrome DevTools, poi applicare
il pattern chunking+yield solo dove necessario. Over-engineering con yield ovunque puo introdurre
overhead inutile; applicalo ai task che sai essere pesanti (elaborazione di grandi dataset,
rendering di molti elementi DOM, computazioni costose).