E se potessimo superare JavaScript e TypeScript nei nostri browser web?
JavaScript è nato come linguaggio di scripting semplice, simile all’allora nascente Java. Nel corso del tempo, sono stati sviluppati numerosi strumenti per migliorare l’efficienza e le prestazioni, tra cui linters, gestori di pacchetti, frameworks e librerie, assicurando che il nostro codice funzionasse su tutti i browser, anche su Internet Explorer 6, notoriamente difficile. Sono stati adottati nuovi paradigmi di programmazione, la programmazione funzionale e l’implementazione di strutture basate su classi, fino a creare intere applicazioni direttamente nell’ambiente del browser. Questa evoluzione ci ha permesso di sfruttare le capacità dei motori V8 oltre i confini tradizionali.
Spesso ci siamo trovati costretti a subire le limitazioni del nostro linguaggio di scripting, esprimendo spesso le nostre preoccupazioni per le sue carenze progettuali, e il più delle volte abbiamo desiderato delle alternative. In risposta, la ByteCode Alliance ha introdotto ASM.js, seguito da WASM: un obiettivo unificato per binari e moduli che operano senza soluzione di continuità all’interno dei nostri browser, rappresentando il codice macchina per il web contemporaneo.
Alcuni sviluppatori sono rimasti colpiti dalla compattezza e portabilità di questi file binari, attribuendolo al runtime WASM altamente astratto. Hanno quindi creato WASI, che migliora WASM nel browser incorporando system calls che consentono agli sviluppatori di interagire con il Web, le interfacce I/O, i socket e altro ancora, indipendentemente dal sistema operativo, dalla piattaforma o dall’architettura.
Questa innovazione ci permette di eseguire un’ampia gamma di applicazioni ovunque WASI sia supportato. WASI trasforma il nostro runtime WASM in macchine virtuali completamente funzionali, senza l’overhead di un sistema operativo tradizionale.
Nel 2024, l’edge computing e la componibilità sono trend importanti per il settore. L’importanza della sicurezza ha raggiunto un livello tale che la Casa Bianca ha rilasciato una dichiarazione a favore dei linguaggi di programmazione memory-safe. Siamo sempre più chiamati a ottenere di più con meno risorse, con l’obiettivo di ridurre al minimo i costi, i tempi e le emissioni. In questo contesto, WASM emerge come una soluzione veloce e compatibile con l’hardware, libera da vincoli specifici del fornitore e agnostica rispetto ai linguaggi di sviluppo.
WASM è ovunque
Durante il recente Codemotion di Milano, ho assistito a un talk di Gridspertise sulla implementazione di WASM e DAPR nella loro infrastruttura.
Mi ha sorpreso scoprire di usare già WASM quotidianamente, semplicemente caricando il mio portatile. Gridspertise è un’azienda che si occupa di soluzioni smart grid e della trasformazione digitale delle reti di distribuzione dell’energia. Offre tecnologie e servizi progettati per assistere le utility nella modernizzazione delle infrastrutture, nel miglioramento dell’efficienza e nell’integrazione delle fonti di energia rinnovabili. La sua esperienza consiste nello sviluppo di sistemi di misurazione avanzati, soluzioni di automazione della rete e piattaforme digitali per la gestione dell’energia.
Le loro operazioni dipendono da dispositivi e sensori at the edge, con la loro infrastruttura cloud che comunica attraverso interfacce coerenti, interpreta le stesse metriche e raccoglie i log in modo uniforme per creare metriche coese. In genere, ciò richiederebbe team separati per IoT, microservizi e dispositivi utente. Tuttavia, sfruttando WASM, è possibile gestire diversi settori con un unico team. Gli speaker hanno esposto anche diversi modi per integrarlo nelle applicazioni per l’esecuzione di modelli LLM e carichi di lavoro su GPU.
WASM opera in un ambiente sandbox, che lo rende intrinsecamente adatto all’incapsulamento e alla distribuzione su varie piattaforme, mentre DAPR è una libreria progettata per applicazioni distribuite che utilizza il pattern sidecar. Questo pattern, come suggerisce il nome, crea una struttura di supporto attorno al servizio, facilitando l’accesso alle risorse e la comunicazione con altri container senza richiedere la conoscenza dell’implementazione sottostante o delle specifiche della piattaforma. Questa astrazione della complessità consente al team di sviluppo di concentrarsi sul mantenimento di una base di codice coerente, indipendentemente dalle questioni legate alla piattaforma.
L’approccio si allinea perfettamente con le tecnologie esistenti: i loro container possono funzionare come pod all’interno di Kubernetes, comunicare con Kafka tramite i protocolli MQTT e gRPC e offrire API in modo simile. WASM non richiede un “avvio a freddo”, spesso necessario per inizializzare le funzioni su varie piattaforme cloud; si può operare direttamente dal runtime di WASM in un ambiente sandbox, senza dover avviare ripetutamente i container. Senza la necessità di eseguire il codice all’interno di una JVM o di un container Linux, si riduce al minimo l’utilizzo della memoria.
Quali sono gli spunti che possiamo trarre come sviluppatori web?
Come già detto, WebAssembly (WASM) ci permette di creare applicazioni utilizzando vari linguaggi di programmazione e di distribuirle sul web. Sono disponibili numerosi framework, come Yew per Rust e Blazor per C#, che orchestrano i nostri applicativi tramite WASM e interagiscono all’esterno con JavaScript. Inoltre, possiamo sfruttare tecnologie come TensorFlow e modelli linguistici di grandi dimensioni (LLM) nei nostri browser, ottenendo livelli di prestazioni più vicini all’esecuzione nativa.
Trovo particolarmente affascinante l’applicazione di questi concetti allo sviluppo front-end.
Possiamo facilmente relazionarci con i nostri colleghi in questo campo, mirando a distribuire applicazioni universali su diverse piattaforme, compresi smartphone e browser web. Il concetto di “micro-frontend” è simile a quello di “micro-servizi”, in cui i singoli moduli operano in modo indipendente, condividono risorse e permessi e comunicano attraverso eventi per mantenere la coerenza. Gli utenti si aspettano esperienze senza soluzione di continuità, come l’aggiornamento in tempo reale del carrello della spesa e delle pagine dei prodotti man mano che vengono aggiunti.
Anche se questo aspetto può non essere così critico come garantire l’accuratezza dei dati dei sensori, ogni dettaglio è importante in settori competitivi come l’e-commerce così come l’online banking e altri servizi rivolti al pubblico; un software affidabile che offra esperienze coinvolgenti agli utenti favorisce la soddisfazione e la fedeltà dei clienti.
È possibile per noi, come sviluppatori web, superare la tradizionale divisione tra sviluppo front-end e back-end?
Posso immaginare un futuro in cui le nostre applicazioni web siano costituite da numerosi moduli di diversi team, che si integrano perfettamente nel browser in modo simile a un’architettura event-driven. In questo modo si creerebbe un’esperienza utente resiliente, anche in caso di guasti ai moduli, senza affidarsi a complesse soluzioni stateful. Potremmo invece implementare una reattività granulare e senza stato, eliminando la necessità di duplicare la logica per la convalida degli input dell’utente, indipendentemente dal fatto che i nostri colleghi del backend usino Scala e noi TypeScript.
Autore: Federico Muzzo, Front-end Developer @ Bitrock