facebook

Blog

Resta aggiornato

Dall’analisi al confronto: l’esperienza di sviluppo
Blazor vs Angular: quale scegliere? Prima parte
mercoledì 10 Febbraio 2021

Una delle domande su Blazor che mi viene fatta più spesso è perché dovrebbe essere scelto come framework di front-end al posto di soluzioni più consolidate come Angular. La risposta è molto semplice: non ci sono ragioni generiche per adottare un framework piuttosto che un altro, quindi non dovreste mai farlo alla cieca! Ma spesso si guardano le cose da punti di vista strettamente funzionali, quando invece nella realtà i requisiti non funzionali fanno la differenza tra il successo e il fallimento di un progetto.

Perché Angular 

Angular è sicuramente un framework molto utilizzato nel mondo Microsoft, probabilmente perché, con l’avvento di .NET Core, fu chiaro che a breve non ci sarebbe stata una soluzione paragonabile e anche perché tra i framework in circolazione era quello più vicino ai programmatori .NET. Questo perché il team di Angular, nel passaggio da AngularJS a Angular 2, decise di adottare TypeScript, un tool Microsoft che rende JavaScript straordinariamente simile a C#.

Stiamo però parlando di un transpilatore che genera codice JavaScript che il browser può eseguire, quindi non un vero e proprio compilatore. La tipizzazione forte, offerta a tempo di compilazione, in realtà non esiste in JavaScript e può essere facilmente aggirata. Nonostante questo, parliamo di una buona soluzione per chi si occupa di front-end Web e vuole risolvere i principali problemi di produttività e manutenibilità di JavaScript, mentre per chi viene dal back-end è un approccio a JavaScript più che ottimo. Se poi si conosce C# si ha quasi l’illusione di un linguaggio conosciuto da sempre.

Perché Blazor 

Se non conosciamo già Angular e TypeScript, però, stiamo comunque incamerando debito tecnico nel team. L’utilizzo corretto di questo framework richiede studio e tempo, spesso anche un team dedicato. Le conoscenze del team e il tempo necessario all’acquisizione di nuove competenze sono un requisito non funzionale spesso sottostimato, che ha un impatto notevole sui progetti. Ecco quindi una buona ragione per utilizzare Blazor: potete riutilizzare le vostre conoscenze del mondo .NET nel browser, sfruttando standard web aperti come WebSocket e WebAssembly, scaricando nel browser le DLL .NET compilate in codice IL (Intermediate Language) ed eseguendo il front-end della vostra applicazione nel browser installato sulla macchina dell’utente.

Ad onor del vero, Blazor è disponibile in due modalità, chiamate Hosting Models: la versione Server e la versione WebAssembly. Nella versione Server, l’esecuzione del codice avviene lato Server e le modifiche all’interfaccia utente (il DOM nel nostro caso) vengono inviate al client utilizzando SignalR, che, nel migliore dei casi, utilizza WebSocket in maniera trasparente al programmatore. Nella versione WebAssembly, invece, le DLL vengono scaricate nel client ed eseguite grazie a un runtime .NET (il runtime del progetto Mono) compilato in WASM, il formato binario dello standard WebAssembly.

Per un confronto equo, ci dobbiamo necessariamente riferire a Blazor WebAssembly, in modo da non avere nessun aiuto dal server, cosa che Angular necessariamente non avrebbe.

Dalla compilazione all’esecuzione

Partiamo dal browser, che è l’ambiente in cui girano entrambi ma in maniera completamente differente. Ad un più alto livello, possiamo vedere il browser come un’ applicazione che ci mette a disposizione HTML e CSS per disegnare la nostra interfaccia e tutta una serie di API con le quali il nostro codice può interagire per manipolare il DOM, accedere agli storage disponibili, comunicare con l’esterno, e tanto altro in completa sicurezza e senza fare nessuna assunzione sul sistema operativo su cui il browser gira.

Possiamo accedere a queste API grazie ad un runtime, chiamato JavaScript Runtime, che garantisce il funzionamento del nostro codice con tutti i limiti di sicurezza necessari in un ambiente del genere (non possiamo accedere al file system direttamente, così come alle periferiche, ad esempio). Il caso più comune di utilizzo del JavaScript Runtime è attraverso gli script JavaScript, che vengono interpretati ed eseguiti proprio da questo runtime.

In Angular partiamo da codice TypeScript, che viene transpilato in codice JavaScript, minificato e bundlizzato da un bundler (tipicamente WebPack) per servire al browser la versione più compatta possibile del codice. Questo codice viene eseguito direttamente nel JavaScript Runtime senza intermediari, quindi con le migliori performance possibili.

In Blazor, partiamo da codice C# che viene compilato in codice IL in un assembly DLL che viene poi servito al browser insieme al runtime Mono compilato in WASM (rinominato in dotnet.wasm) e alle DLL del framework .NET necessarie all’applicazione. In questo caso, il codice IL non viene eseguito direttamente nel JavaScript Runtime, ma caricato ed eseguito dal runtime Mono compilato in WASM.

Come vedremo parlando di performance, questa differenza di funzionamento impatta notevolmente sui tempi di esecuzione, che può quindi essere uno dei fattori di scelta tra i due.

Un possibile confronto

Per confrontare i due framework, è necessaria una buona conoscenza di entrambi per valutare gli aspetti salienti in maniera oggettiva e soprattutto contestualizzata, cercando di capire quando ha senso usare uno piuttosto che l’altro, senza fanatismi.  

Inoltre, i possibili piani su cui eseguire un confronto sono tantissimi, quindi limiteremo il campo a tre fattori specifici, che sono l’esperienza di sviluppo, intesa come l’insieme degli strumenti disponibili e il modo con cui è possibile sviluppare applicazioni, le funzionalità messe a disposizione dai due framework e le performance, non necessariamente di pura esecuzione, ma anche di tempi di attesa di compilazione e download. 

Dato che ognuno di questi tre punti merita un articolo separato, cominciamo qui con l’esperienza di sviluppo, mentre nei prossimi articoli esamineremo funzionalità e performance. 

Esperienza di Sviluppo

Entrambi i framework mettono a disposizione una CLI (Command Line Interface) cross-platform per eseguire la creazione, la compilazione, l’esecuzione e il deploy di progetti. Per entrambi, è possibile usare diversi editor a pagamento o gratuiti (come Visual Studio Code), per i quali sono disponibili dei plugin specifici a supporto dello sviluppo. Possiamo anche usare degli IDE completi come Visual Studio su Windows o Visual Studio for Mac su macOS, a seconda delle nostre preferenze o abitudini.

Personalmente, preferisco Visual Studio Code per lo sviluppo front-end, mentre utilizzo Visual Studio quando mi occupo dello sviluppo di tutti i layer utilizzando lo stack Microsoft: l’esperienza di sviluppo nel passaggio da front-end a back-end e viceversa è sicuramente più produttiva con un ambiente integrato. In questo specifico caso, se sviluppate su Windows con Blazor per il front-end e .NET per il back-end, l’esperienza con Visual Studio è ovviamente migliore che con Angular, vista la forte integrazione tra i prodotti della stessa casa madre. Con Angular continuo a preferire Visual Studio Code e il suo terminale integrato, i plug-in disponibili per Angular sono davvero tanti e comodi.

Qualsiasi ambiente usiate, l’esperienza di debug di Angular al momento è più semplice e completa. Nello sviluppo front-end, mi piace fare una differenza sostanziale tra due possibili approcci al debug di quello che realizziamo. La prima vede l’inserimento di un punto di interruzione nel codice per poter esaminare passo passo la logica implementata e ispezionare i valori delle variabili, la seconda è quella che invece utilizza massicciamente il Live Reload, cioè il rebuild e refresh automatico nel browser della pagina su cui si sta lavorando.

Quando utilizziamo i punti di interruzione con il browser, abbiamo due possibilità: o farlo direttamente con i tool di sviluppo offerti dal nostro browser preferito, oppure agganciare il debugger del browser dal nostro ambiente di sviluppo. In entrambi i casi, è necessario esaminare il codice originale per capirci qualcosa, quindi C# per Blazor e TypeScript per Angular. Nel caso di Blazor, però, abbiamo un doppio passaggio che vede coinvolti C#, il codice intermedio (IL) e la sua traduzione in WebAssembly da parte del runtime di Mono. In Angular, invece, passiamo direttamente da TypeScript a JavaScript, quindi la cosa è notevolmente più semplice. Inoltre, il browser ha un supporto nativo e consolidato per il debug di JavaScript, mentre non è così invece per WebAssembly, che, tra l’altro, essendo un formato binario potenzialmente generabile da qualsiasi linguaggio di alto livello, rende il debug nativamente ostico.

Nonostante tutto questo, Blazor WebAssembly offre la possibilità di inserire punti di interruzione nel codice e debuggare il codice C# originale, con una esperienza tutto sommato comoda (notevolmente migliorata con .NET 5) se non fatta direttamente nel browser (esiste, ma l’usabilità lascia a desiderare) e in ogni caso non paragonabile a quella JavaScript.

Anche con il Live Reload, devo dire che l’esperienza multi-browser offerta dalla CLI di Angular è molto più comoda e stabile di quella offerta dalla CLI di .NET, che è stata introdotta proprio in .NET 5. Questo perché, mentre in Angular riuscite ad avere il refresh su più browser aperti sulla vostra applicazione, con Blazor solo un browser per volta può essere aggiornato. Può sembrare poca cosa, ma se fate sviluppo cross-browser, nonostante tutti gli standard attuali, capita spesso di dover provare la propria applicazione su browser differenti (a volte anche sistemi operativi differenti) e magari in diverse modalità (desktop, tablet o mobile). Niente di insuperabile, ma è un aspetto di cui tener conto. Inoltre, in Blazor questa modalità funziona solo senza il debugger attivato, quindi non potete avere contemporaneamente Live Reload e punti di interruzione, cosa che invece avete in Angular.

In tutti i framework di front-end moderni, l’interfaccia è un insieme di componenti, quindi come realizzare un componente in uno specifico framework diventa fondamentale. Inoltre, una Single Page Application si basa su meccanismi di routing che permettono di simulare la navigazione tra diverse pagine logiche, visto che fisicamente la pagina è una sola: il modo in cui posso istruire il motore di routing è quindi un altro aspetto fondamentale.

Da questi punti di vista Angular e Blazor hanno due approcci completamente differenti. Angular basa il suo funzionamento su una dichiarazione esplicita di tutti i parametri, quindi offre una forte configurabilità che però significa anche dover specificare ogni singola opzione diversa dai default. In Blazor, come nei principali framework web Microsoft, invece si predilige un approccio più basato su convenzioni che su configurazioni (Convention Over Configuration), rendendo spesso più immediato l’utilizzo del framework a scapito di una configurabilità più ostica.

Conclusioni

Per il momento ci fermiamo qui, sperando di averti dato qualche informazione utile per cominciare a ragionare su quale framework scegliere per il tuo prossimo progetto. Nei prossimi articoli, analizzeremo le funzionalità e le performance, per completare il confronto e darti i principali strumenti per fare la scelta giusta.

Se hai delle domande o vuoi fare una chiacchierata con noi su questi temi, puoi contattarci utilizzando l’apposito form e leggere gli altri articoli del nostro blog o guardare le registrazioni dei talk che parlano di Blazor.

Happy Coding!