Negli ultimi anni lo sviluppo di applicazioni web basate su React ha visto l’emergere di nuovi framework, ognuno con un approccio unico per semplificare il processo di creazione di applicazioni moderne e ad alte prestazioni.
Uno di questi framework che ha catturato l’attenzione della comunità degli sviluppatori è Remix, ideato dai noti creatori di React Router, Ryan Florence e Michael Jackson. Ma cosa rende Remix una valida alternativa a Next.js, uno dei framework React più affermati?
Caratteristiche di Remix
Remix è un framework di sviluppo web basato su React. È stato progettato per semplificare il processo di sviluppo delle moderne applicazioni web e offre una vasta gamma di funzionalità avanzate.
Ecco alcune delle caratteristiche principali che rendono Remix interessante per gli sviluppatori:
Server-Side Rendering
La caratteristica principale di Remix è il Server-Side Rendering (SSR) che genera il markup e il contenuto delle nostre pagine dal server web prima di inviarle al client. I vantaggi di questa tecnica sono numerosi:
- Caricamento iniziale della pagina più rapido: Poiché la pagina HTML completamente renderizzata viene inviata dal server, il tempo necessario al browser per scaricare ed elaborare i file JavaScript si riduce, migliorando così l’esperienza dell’utente.
- Miglioramento della SEO: Le pagine sono più facili da scansionare e indicizzare perché il loro contenuto HTML è reso disponibile in anticipo. Questo migliora la visibilità delle pagine web nelle classifiche dei motori di ricerca e contribuisce a indirizzare il traffico verso il sito web.
- Miglioramento dell’esperienza dell’utente: Con l’SSR, gli utenti ricevono una pagina prerenderizzata dal server, che consente loro di visualizzare i contenuti più rapidamente e di navigare nel sito web senza soluzione di continuità, offrendo un’esperienza utente più fluida e coinvolgente.
- Funzionalità multipiattaforma: L’SSR garantisce un rendering coerente su vari dispositivi e piattaforme, compresi browser, sistemi operativi e dimensioni dello schermo diverse. Generando l’HTML sul server, SSR riduce le discrepanze associate al Client-Side Rendering (CSR) e garantisce un’esperienza coerente per tutti gli utenti.
Ecco alcune caratteristiche aggiuntive di Remix che possono snellire il processo di sviluppo:
- Percorsi annidati: Remix consente di gestire più percorsi diversi utilizzando file JavaScript/TypeScript che contengono funzioni di gestione. I file creati vengono gestiti da React Router 6, che li utilizza per generare i rispettivi URL, seguendo la gerarchia del file system.
- Gestione semplificata dei moduli: Una delle caratteristiche principali di Remix è il modo in cui mantiene automaticamente l’interfaccia utente sincronizzata con lo stato del server. Ciò avviene in tre fasi: i route loaders forniscono dati all’interfaccia utente, i moduli inviano dati alle route actions che aggiornano lo stato persistente e i dati del loader sulla pagina vengono automaticamente riconvalidati. La gestione dei moduli è gestita principalmente dalle funzioni “action” e “loader”: queste funzioni sono integrate, quindi i loro nomi non possono essere sovrascritti. Quando l’utente invia i dati attraverso il modulo, vengono eseguite una serie di operazioni: Remix invia i dati alla funzione action; una volta completata l’azione, viene invocata la funzioneloader per ottenere il nuovo stato dal server, e utilizzando l’hook useLoaderData vengono recuperati i dati inviati dal server.
- Gestione centralizzata dello stato: Con Remix, è possibile gestire gli stati lato server e lato client direttamente all’interno dei componenti dell’applicazione: un aspetto cruciale, perché elimina la necessità di strumenti esterni come Redux. Ad esempio, è possibile scoprire quando una pagina si trova nello stato “submitting”, che indica che i dati del modulo sono in fase di invio.
- Gestione ottimizzata degli errori: Remix consente la gestione diretta degli errori all’interno del componente, assicurando che, in caso di problemi, l’errore venga visualizzato solo nel componente in cui si è verificato, impedendo che si blocchi l’intera applicazione e interrompa l’esperienza dell’utente. La gestione degli errori è gestita tramite la funzione ErrorBoundary, che viene invocata quando si verifica un errore nel componente, oltre che durante le funzioni di loader e di azione. In particolare, nel caso di queste ultime e durante il rendering, si entra nel blocco if RouteErrorResponse.
Principali differenze tra Remix e Next.js
Sebbene esistano diversi framework basati su React, Next.js spicca tra questi. È quindi utile analizzare le differenze tra questi due strumenti per capire meglio quale possa essere considerato migliore per lo sviluppo di applicazioni web.
Static Site Generators
Una delle principali differenze tra Next.js e Remix è l’uso degli Static Site Generators (SSGs), che Remix non supporta. In qualsiasi applicazione che lo utilizzi, è possibile che si verifichi uno scenario non supportato da SSG, in particolare le pagine dinamiche. Se non è possibile utilizzare gli SSG, l’applicazione recupera i risultati della ricerca dal browser dell’utente, rallentando il processo di recupero delle informazioni.
D’altra parte, Remix è più veloce perché, senza supportare gli SSG, utilizza SWR (HTTP stale-while-revalidate) o Redis per gestire la cache delle informazioni nei browser. La differenza di velocità diventa evidente quando gli SSGs di Next.js non possono essere utilizzati. Next.js ha introdotto la cosiddetta “network waterfall request chain“, che comporta un ritardo nel caricamento degli elementi della pagina, poiché i dati vengono recuperati solo dopo che il codice JavaScript è stato caricato, analizzato e valutato. Con Remix, avere un unico modo dinamico di generare le pagine permette di modificare la gestione della cache senza alterare il codice.
Layout
Un’altra differenza tra i due strumenti riguarda la struttura delle cartelle per la creazione delle pagine e dei layout. In Remix, le pagine e i rispettivi layout vengono creati in base al nome del file. Per Next.js, la distinzione tra pagine e layout si basa sul nome del file. I file di Next.js sono organizzati in cartelle e sottocartelle. All’interno di questa struttura, è possibile creare il file “page.tsx” per stabilire un percorso o “layout.tsx” per creare un layout specifico per la pagina.
Nonostante ciò, la possibilità di creare file come “loading.tsx” o “error.tsx” in aggiunta a queste due pagine aiuta a definire e separare gli stati delle pagine in modo più comprensibile. D’altra parte, basta leggere il nome del file per comprenderne immediatamente il contenuto, quindi la struttura di Remix può essere considerata più intuitiva.
Data Fetching
In Remix, abbiamo osservato come vengono recuperati i dati utilizzando la funzione loader e il suo hook corrispondente, la funzione useLoaderData. Poiché è possibile definire un loader su ogni percorso, compresi i layout, i dati possono essere caricati in parallelo anziché in sequenza.
Per quanto riguarda Next.js, con l’introduzione di Next.js 13, si è passati dalla definizione della logica di reperimento dei dati esclusivamente sul lato server utilizzando “getServerSideProps” e “getStaticProps” all’adozione di React Server Components (RSC). Gli RSC sono componenti che vengono renderizzati esclusivamente sul server e, a differenza del tradizionale rendering lato server di React, non vengono mai idratati sul client. Questo comporta vantaggi quali il recupero dei dati e la sicurezza, in quanto i dati non sono mai esposti al client, e le dimensioni deterministiche dei bundle, poiché i componenti sul server non vengono scaricati sul client ma rimangono sul server. Tuttavia, questo strumento presenta anche degli svantaggi, in quanto questi componenti non possono contenere parti interattive dell’interfaccia utente, come useState e useEffect, e gestori di eventi.
Inoltre, non è possibile importare un componente server in un client, poiché il componente server viene eseguito solo sul server.Nonostante la comodità delle funzioni loader e la possibilità di caricare i dati in parallelo offerta da Remix, i componenti server di Next.js sono attualmente considerati più utili. Ciò è dovuto ai vari vantaggi descritti in precedenza e all’eccellente esperienza degli sviluppatori. Essi consentono di comporre l’albero dei componenti in modo da recuperare i dati esattamente dove devono essere, anziché solo nei segmenti di percorso.
Data Mutations
Remix incoraggia l’uso di ogni parte dell’applicazione in cui l’utente compie un’azione, come ad esempio un modulo HTML. In questo modo, gli sviluppatori hanno la possibilità di gestire un’applicazione utilizzando un “flusso di dati full-stack” con action e loader.
Con la versione 13.4 di Next.js sono state introdotte le azioni server, che sostituiscono gli endpoint API. Con le azioni server, è possibile creare facilmente funzioni server asincrone che possono essere richiamate direttamente dai componenti, fornendo l’accesso a tutte le utility solo server come cookie, revalidate, redirect e altro ancora.
L’approccio di Remix è semplice e completo per creare un’applicazione full-stack di flussi di dati, migliorando così sia l’esperienza dell’utente che quella dello sviluppatore. Tuttavia, con l’aumentare della complessità, potrebbe essere necessario utilizzare la funzione action in più punti dell’applicazione, il che richiede la specificazione dell’URL della funzione action nel corrispettivo attributo del form. Questo può generare confusione quando si cerca di individuare il file che esegue l’azione. Le azioni server di Next.js risolvono questo problema consentendo di creare funzioni e importarle dove necessario all’interno dell’applicazione.
La Community
Next.js è in circolazione da un po’ di tempo e vanta un’ampia comunità. In caso di problemi o necessità di supporto è probabile che qualcun altro abbia già affrontato lo stesso problema e trovato una soluzione. Inoltre, sono disponibili diversi pacchetti per molti casi d’uso. Ad esempio, NextAuth è uno di questi pacchetti, spesso usato per aggiungere l’autenticazione a un’applicazione web.
D’altra parte, Remix, essendo relativamente nuovo, sta ancora sviluppando il suo ecosistema. Questo significa che per alcuni problemi potrebbe non essere disponibile un supporto
Conclusioni
Remix può essere considerato un framework potente, che emerge come una valida alternativa al più popolare Next.js. Mentre Next.js mantiene la sua popolarità, le caratteristiche uniche di Remix possono avere un impatto significativo sulle decisioni di sviluppo.
La scelta tra i due dipende dalle priorità specifiche del progetto, dalle preferenze di sviluppo del team e dalla familiarità con entrambi i framework.
Autore: Marika Fabiani, Junior Front-end Developer @ Bitrock