Le librerie e i framework JavaScript non mancano di certo agli sviluppatori web moderni. Una delle librerie più diffuse è React, creata da Facebook (ora Meta) per aiutare a costruire applicazioni ricche di funzionalità. Le applicazioni React vengono tradizionalmente eseguite nei browser web, ma il framework Next.js estende le funzionalità di React al lato server attraverso l’ambiente di runtime JavaScript Node.js.

In questo articolo analizzeremo Next.js e React per aiutarvi a decidere se sono adatti al vostro prossimo progetto.

Next.js e React: JavaScript di Livello Superiore

Un’indagine di SlashData del 2022 ha rilevato che ci sono più di 17 milioni di programmatori JavaScript nel mondo, in testa a un gruppo che comprende linguaggi popolari come Python e Java. JavaScript può essere utilizzato sia sul lato client che su quello server e questa versatilità consente agli sviluppatori di creare applicazioni complete utilizzando un unico linguaggio di programmazione.

Sondaggio Slash/Data sui linguaggi utilizzati dai programmatori nel 2022.
Sondaggio Slash/Data sui linguaggi utilizzati dai programmatori nel 2022. (Fonte: Statista)

L’introduzione di librerie JavaScript come React e di framework come Next.js ha favorito ulteriormente questo sviluppo. Queste librerie e framework forniscono funzionalità che semplificano l’integrazione tra frontend e backend. Inoltre, gli sviluppatori possono estendere le funzionalità di JavaScript utilizzando gestori di pacchetti come npm (il gestore di pacchetti di Node.js) per installare librerie e strumenti JavaScript. Queste risorse offrono funzionalità sofisticate che riducono la quantità di codice da scrivere.

L’estensibilità di JavaScript implica che una conoscenza completa degli strumenti più comuni è fondamentale per il proprio successo come sviluppatore web.

Cos’è Next.js?

Rilasciato inizialmente nel 2016 da Vercel, Next.js è un framework React open-source che fornisce gli elementi fondamentali per creare applicazioni web ad alte prestazioni. Da allora lo hanno adottato importanti aziende, tra cui Twitch, TikTok e Uber, solo per citarne alcune.

Next.js offre una delle migliori esperienze di sviluppo per la creazione di applicazioni veloci e SEO-friendly. Di seguito elenchiamo alcune caratteristiche di Next.js che lo rendono un framework di produzione eccezionale:

  • Funzionalità di rendering ibrido
  • Suddivisione automatica del codice
  • Ottimizzazione delle immagini
  • Supporto integrato per preprocessori CSS e librerie CSS-in-JS
  • Routing integrato

Queste caratteristiche aiutano gli sviluppatori di Next.js a risparmiare molto tempo sulla configurazione e sugli strumenti. È possibile passare direttamente alla creazione della propria applicazione, che potrebbe supportare progetti come i seguenti:

  • Negozi di e-commerce
  • Blog
  • Dashboard
  • Applicazioni a pagina singola
  • Interfacce utente interattive
  • Siti web statici

Cos’è React?

React è una libreria JavaScript utilizzata per creare interfacce utente dinamiche. Oltre a creare interfacce web, è possibile creare applicazioni mobili utilizzando React Native.

Alcuni vantaggi dell’uso di React sono:

  • Migliori prestazioni: Invece di aggiornare ogni componente del DOM, React utilizza un DOM virtuale per aggiornare solo i componenti modificati.
  • Fortemente basato sui componenti: Una volta creato un componente, si può riutilizzare più volte.
  • Semplicità di debug: Le applicazioni React utilizzano un flusso di dati unidirezionale, solo dai componenti genitore e figlio.

Next.js vs React

Sebbene gli sviluppatori utilizzino spesso Next.js e React per lo stesso scopo, ci sono alcune differenze fondamentali tra i due.

Semplicità d’Uso

Iniziare con Next.js e React è semplice. Ciascuno di essi richiede l’esecuzione di singoli comandi nel proprio terminale utilizzando npx, che fa parte di npm per Node.js.

Per Next.js, il comando più semplice è:

npx create-next-app

Senza ulteriori argomenti per create-next-app, l’installazione procederà in modalità interattiva. Vi verrà chiesto il nome del progetto (che verrà utilizzato per la directory del progetto) e se volete includere il supporto per TypeScript e il code linter ESLint.

L’aspetto sarà simile a questo:

Creazione di un'applicazione Next.js in modalità interattiva.
Creazione di un’applicazione Next.js in modalità interattiva.

Quando si inizializza un’istanza di React, il comando più semplice include un nome per la directory del progetto:

npx create-react-app new-app

Questo genera una cartella contenente tutte le configurazioni e le dipendenze iniziali necessarie:

Creare un progetto React dalla riga di comando del terminale.
Creare un progetto React dalla riga di comando del terminale.

Sebbene sia semplice cominciare con entrambi, ricordate che Next.js è costruito sulla base di React. Quindi, non è possibile imparare Next.js senza prima aver imparato React e aver capito come funziona. Fortunatamente, React ha una curva di apprendimento molto dolce ed è ottimo per i principianti.

È importante anche notare che React è relativamente poco strutturato. È necessario installare e configurare un router React e decidere come gestire il recupero dei dati, l’ottimizzazione delle immagini e la suddivisione del codice. Questa configurazione richiede l’installazione e la configurazione di librerie e strumenti aggiuntivi.

Al contrario, Next.js viene fornito con questi strumenti preinstallati e preconfigurati. Con Next.js, qualsiasi file aggiunto alla cartella pages funge automaticamente da percorso. Grazie a questo supporto integrato, Next.js è più facile da usare quotidianamente e permette di iniziare subito a sviluppare la logica della propria applicazione.

Caratteristiche di Next.js e React

Poiché Next.js si basa su React, le due applicazioni condividono alcune caratteristiche. Tuttavia, Next.js fa un passo avanti e include funzionalità aggiuntive come il routing, la suddivisione del codice, il pre-rendering e il supporto alle API. Si tratta di funzionalità che dovrete configurare voi stessi quando usate React.

Recupero dei Dati

React esegue il rendering dei dati sul lato client. Il server invia file statici al browser, che poi recupera i dati dalle API per popolare l’applicazione. Questo processo riduce le prestazioni dell’applicazione e offre una scarsa esperienza all’utente perché l’applicazione si carica lentamente. Next.js risolve questo problema grazie al pre-rendering.

Con il pre-rendering, il server effettua le chiamate API necessarie e recupera i dati prima di inviare l’applicazione al browser. In questo modo, il browser riceve pagine web pronte per il rendering.

Il pre-rendering può riferirsi alla generazione di siti statici (SSG) o al rendering lato server (SSR). In SSG, le pagine HTML vengono generate al momento della creazione e riutilizzate per più richieste. Next.js può generare pagine HTML con o senza dati.

Di seguito è riportato un esempio di come Next.js genera pagine senza dati:

function App() {
  return <div>Welcome</div>
}
export default App

Per le pagine statiche che consumano dati esterni, utilizza la funzione getStaticProps(). Una volta esportato getStaticProps() da una pagina, Next.js effettuerà il pre-rendering della pagina utilizzando i props che restituisce. Questa funzione viene sempre eseguita sul server, quindi utilizza getStaticProps() quando i dati utilizzati dalla pagina sono disponibili al momento della creazione. Ad esempio, potete usarla per recuperare i post di un blog da un CMS.

const Posts= ({ posts }) => {
    return (
        <div className={styles.container}>
            {posts.map((post, index) => (
                // render each post
            ))}
        </div>
    );
  };

export const getStaticProps = async () => {
    const posts = getAllPosts();
    return {
        props: { posts },
    };
};

Nelle situazioni in cui i percorsi delle pagine dipendono da dati esterni, utilizzate la funzione getStaticPaths(). Quindi, per creare un percorso basato sull’ID del post, esportate getStaticPaths() dalla pagina.

Ad esempio, è possibile esportare getStaticPaths() da pages/posts/[id].js come mostrato di seguito.

export getStaticPaths = async()  => {
  // Get all the posts
  const posts = await getAllPosts()

  // Get the paths you want to pre-render based on posts
  const paths = posts.map((post) => ({
    params: { id: post.id },
  }))
  return { paths, fallback: false }
}

getStaticPaths() è spesso abbinato a getStaticProps(). In questo esempio, utilizzerete getStaticProps() per ottenere i dettagli dell’ID nel percorso.

export const getStaticProps = async ({ params }) => {
    const post = await getSinglePost(params.id);
    return {
        props: { post }
    };
};

In SSR, i dati vengono recuperati al momento richiesto e inviati al browser. Per utilizzare SSR, esportate la funzione props getServerSide() dalla pagina che volete renderizzare. Il server richiama questa funzione a ogni richiesta, il che rende SSR utile per le pagine che consumano dati dinamici.

Ad esempio, potete usarla per recuperare i dati da un’API di notizie.

const News = ({ data }) => {
    return (
        // render data
    );
  };

export async function getServerSideProps() {
    const res = await fetch(`https://app-url/data`)
    const data = await res.json()
    return { props: { data } }
}

I dati vengono recuperati a ogni richiesta e passati al componente News tramite i props.

Code Splitting

Il code splitting consiste nel dividere il codice in parti che il browser può caricare su richiesta. Riduce la quantità di codice inviato al browser durante il caricamento iniziale, in quanto il server invia solo ciò di cui l’utente ha bisogno. Bundler come Webpack, Rollup e Browserify supportano la suddivisione del codice in React.

Next.js supporta il code splitting in modo immediato.

Con Next.js, ogni pagina viene sottoposta a code-splitting e l’aggiunta di pagine all’applicazione non aumenta le dimensioni del bundle. Next.js supporta anche le importazioni dinamiche, che consentono di importare moduli JavaScript e di caricarli dinamicamente durante l’esecuzione. Le importazioni dinamiche contribuiscono ad aumentare la velocità delle pagine perché i bundle vengono caricati in modo asincrono.

Ad esempio, nel componente Home qui sotto, il server non includerà il componente hero nel bundle iniziale.

const DynamicHero = dynamic(() => import('../components/Hero'), {
  suspense: true,
})

export default function Home() {
  return (
    <Suspense fallback={`Loading...`}>
      <DynamicHero />
    </Suspense>
  )
}

Invece, l’elemento di fallback della suspense sarà reso prima del caricamento del componente hero.

Supporto API in Next.js vs React

La funzione di routing API di Next.js vi permette di scrivere codice backend e frontend nella stessa codebase. Qualsiasi pagina salvata nella cartella /pages/api/ viene mappata sulla rotta /api/* e Next.js la tratta come un endpoint API.

Ad esempio, è possibile creare una rotta API pages/api/user.js che restituisca il nome dell’utente corrente in questo modo:

export default function user(req, res) {
    res.status(200).json({ username: 'Jane' });
}

Se visitate l’URL https://app-url /api/user, vedrete l’oggetto username.

{
        username: 'Jane'
}

Le rotte API sono utili quando si desidera mascherare l’URL di un servizio a cui si sta accedendo o si vogliono mantenere segrete le variabili d’ambiente senza dover codificare un’intera applicazione backend.

Prestazioni

Next.js è indubbiamente superiore per la sua capacità di creare applicazioni più performanti con un processo semplificato. Le applicazioni SSR e SSG Next.js hanno prestazioni migliori rispetto alle applicazioni React con rendering lato client (CSR). Recuperando i dati sul server e inviando al browser tutto ciò che serve per il rendering, Next.js elimina la necessità di richiedere dati alle API. Questo significa tempi di caricamento più rapidi.

Inoltre, poiché Next.js supporta il routing lato client, il browser non deve recuperare i dati dal server ogni volta che l’utente passa a un altro percorso. Inoltre, il componente immagine di Next.js consente l’ottimizzazione automatica delle immagini. Le immagini vengono caricate solo quando entrano nel viewport. Dove possibile, Next.js serve anche immagini in formati moderni come WebP.

Next.js offre anche l’ottimizzazione dei font, il prefetching intelligente dei percorsi e l’ottimizzazione del bundling. Queste ottimizzazioni non sono automaticamente disponibili in React.

Supporto

Poiché React esiste da più tempo di Next.js, ha una comunità più ampia. Tuttavia, molti sviluppatori di React stanno adottando Next.js, quindi la comunità è in costante crescita. Gli sviluppatori trovano più facilmente soluzioni esistenti ai problemi che incontrano, invece di doverle costruire da zero.

Next.js dispone inoltre di un’eccellente documentazione con esempi completi e di facile comprensione. Nonostante la sua popolarità, la documentazione di React non è altrettanto navigabile.

Riepilogo

La scelta di Next.js o React dipende dai requisiti dell’applicazione.

Next.js migliora le funzionalità di React fornendo una struttura e degli strumenti che migliorano le prestazioni. Questi strumenti, come il routing, il code splitting e l’ottimizzazione delle immagini, sono integrati in Next.js, il che significa che gli sviluppatori non devono configurare nulla manualmente. Grazie a queste caratteristiche, Next.js è facile da usare e gli sviluppatori possono iniziare a sviluppare la logica aziendale immediatamente.

Grazie alle diverse opzioni di rendering, Next.js è adatto per applicazioni renderizzate lato server o per applicazioni che combinano la generazione statica e il rendering lato server di Node.js. Inoltre, grazie alla funzione di ottimizzazione offerta da Next.js, è perfetto per i siti che devono essere veloci, come i negozi di e-commerce.

React è una libreria JavaScript che può aiutarti a creare e scalare applicazioni front-end robuste. La sua sintassi è semplice, soprattutto per gli sviluppatori con un background in JavaScript. Inoltre, avete il controllo sugli strumenti che utilizzate nella vostra applicazione e su come configurarli.

State progettando la vostra applicazione per imporvi sul mercato? Scoprite l’approccio di Kinsta all’Hosting di Applicazioni Node.js per i servizi che supportano React e Next.js.

Salman Ravoof

Salman Ravoof is a self-taught web developer, writer, creator, and a huge admirer of Free and Open Source Software (FOSS). Besides tech, he's excited by science, philosophy, photography, arts, cats, and food. Learn more about him on his website, and connect with Salman on Twitter.