E-commerce
Sincronizzare il magazzino: dove si perde tempo
Confrontare 50.000 SKU con una Map costa 14,94 ms, con una ricerca lineare 11,87 s: il tempo non si perde nel confronto ma nei 3,88 MB di payload e nella verità unica.
In sintesi
- Su 50.000 SKU il confronto con Map costa 14,94 ms, la ricerca lineare 11.868,2 ms: 794 volte tanto.
- Su 10.000 SKU la differenza è 3,72 ms contro 395,5 ms, con 500 quantità cambiate rilevate in entrambi i modi.
- Un feed di 50.000 SKU con SKU, quantità, prezzo e data pesa 3.877.891 byte in JSON e 248.356 byte compresso: il trasporto costa più del confronto.
- Gli artt. 20-23 del Codice del Consumo puniscono la disponibilità dichiarata e non vera come pratica ingannevole: il ritardo di sincronizzazione è un rischio legale, non solo tecnico.
Sincronizzare il magazzino costa poco se confronti due elenchi con la struttura giusta: 50.000 SKU in 14,94 ms con una Map, contro 11,87 secondi con una ricerca lineare. Il tempo che perdi davvero sta altrove: nel payload da 3,88 MB, nei webhook persi e nel decidere quale sistema ha ragione.
Il confronto non è il collo di bottiglia
La differenza fra 14,94 ms e 11,87 s è enorme e insegna una cosa sola: non confrontare due elenchi con due cicli annidati. Con una Map costruita una volta sola il confronto è lineare, e a 50.000 SKU resta sotto i 15 ms. Se il tuo import richiede minuti, il problema non è il numero di prodotti: è il database interrogato una volta per riga, o il file parsato a ogni giro.
Dove finisce il tempo: nel payload
3.877.891 byte per 50.000 SKU sono 77 byte per prodotto, e 248.356 byte compressi sono 5 byte per prodotto: gzip toglie il 94% perché i campi si ripetono. Se sincronizzi ogni cinque minuti, sono 288 trasferimenti al giorno, 1,1 GB di JSON o 71 MB compressi. La stessa informazione come lista di differenze, solo SKU e quantità cambiati, pesa 5.000 righe, non 50.000: la prima ottimizzazione è non spedire ciò che non è cambiato.
Una sola sorgente di verità
Il negozio e il gestionale non possono avere entrambi ragione. Scegli il sistema che possiede la quantità fisica, di solito il gestionale o l'ERP, e tratta la disponibilità mostrata come una copia con data. Se il negozio vende e il gestionale non lo sa, l'ordine verrà rifiutato: è overselling, e costa due volte, perché il cliente ha già pagato. Se il gestionale scala e il negozio non lo sa, mostri prodotti esauriti e perdi vendite. La prima è un rischio legale, la seconda un costo commerciale, e la scelta va scritta nel progetto.
Il diff in una riga
La funzione qui sotto prende l'elenco del magazzino e quello del negozio e restituisce solo le differenze, in una passata. È la versione minima di quello che serve: nella pratica aggiungi la gestione delle righe nuove e di quelle sparite, e il timestamp dell'ultimo aggiornamento per prodotto, che è l'informazione più utile in caso di contestazione.
node -e "const a=[{sku:'A',q:1},{sku:'B',q:2}],b=[{sku:'A',q:1},{sku:'B',q:0}];const m=new Map(a.map(p=>[p.sku,p.q]));console.log(b.filter(p=>m.get(p.sku)!==p.q).map(p=>p.sku+' '+m.get(p.sku)+'->'+p.q).join(', '))"
Webhook, polling e ordine degli eventi
Cosa mostrare quando il dato è vecchio
Nessuna sincronizzazione è istantanea, quindi la pagina deve dire quando è stata aggiornata: «disponibilità aggiornata alle 14:32» è un'informazione onesta e costa una riga di codice. Quando la quantità non è certa, meglio «ultimi pezzi, spedizione in 2-3 giorni» che «disponibile»: la disponibilità dichiarata e non vera è una pratica ingannevole ai sensi degli artt. 20-23 del Codice del Consumo, e con le vendite a distanza il consumatore può recedere comunque, quindi l'ordine annullato è un danno doppio. Se un prodotto finisce mentre l'ordine è in corso, l'unica strada corretta è avvisare subito e proporre attesa o rimborso.
Il limite
I numeri misurano il confronto in memoria su elenchi già caricati: in produzione il tempo lo decidono la latenza dell'API del gestionale e le query del database, che su 50.000 righe possono valere secondi. Il test non copre la concorrenza: due processi che scrivono la stessa quantità nello stesso istante richiedono un lock o una scrittura condizionale, e nessun benchmark in un solo processo lo mostra. E il 5% di modifiche è un valore di prova: nel tuo negozio la percentuale reale cambia il costo del payload, non quello del confronto.
Da dove partire
Domande frequenti
Ogni quanto va sincronizzato il magazzino?
Dipende dalla velocità di vendita: un prodotto che vende dieci pezzi al giorno non ha bisogno di un aggiornamento al minuto, uno che vende dieci pezzi all'ora sì. La regola pratica è sincronizzare a un intervallo più corto del tempo medio fra due vendite dello stesso SKU, e comunque ricevere un evento immediato quando un ordine viene evaso.
Meglio webhook o polling?
Entrambi, per ragioni diverse: il webhook arriva subito ma può perdersi, il polling converge sempre ma con ritardo. Usa il webhook per gli eventi di magazzino e un polling periodico come rete di sicurezza, con un allarme quando i due sistemi divergono.
Come evito di vendere prodotti esauriti?
Trattando la quantità mostrata come una copia con data, non come una verità: aggiorna spesso, mostra l'ora dell'ultimo aggiornamento, e verifica la disponibilità al momento dell'ordine prima di incassare. Se il prodotto è finito, avvisa subito e offri attesa o rimborso.
Quanto pesa un feed di 50.000 SKU?
3.877.891 byte in JSON con SKU, quantità, prezzo e data, e 248.356 byte compresso con gzip, che toglie il 94% perché i campi si ripetono. Spedire solo le differenze riduce il payload di un ordine di grandezza.
Perché il mio import richiede minuti?
Quasi sempre per una query per riga o per un confronto con due cicli annidati. Con una Map costruita una volta sola, 50.000 SKU si confrontano in 14,94 ms; se il processo dura minuti, il tempo è nel database o nel parsing, non nel confronto.