Next.js v14: Quando il Client ed il Server diventano un’unica Astrazione (1/2)

La nuova versione di Next.js porta freschezza ed entusiasmo nel mondo del frontend. Nonostante il settore sia già in costante evoluzione, con una concorrenza agguerrita tra vari competitor, è proprio questa dinamicità che spinge ogni tecnologia a migliorarsi ulteriormente, ottimizzando l'esperienza di sviluppo o adeguando le proprie tecniche alle esigenze attuali del web.

Next.js compie un passo avanti, consolidando le funzionalità introdotte nella versione 13 e rilasciandole dalla beta nella versione 14, tra cui i Server Component (trattati in questo articolo) e le Server Action (che vedremo nel prossimo).

 

Cos’è Next.js

Next.js è un framework React che semplifica lo sviluppo di applicazioni web, aggiungendo funzionalità avanzate per migliorare le performance e l'architettura delle app.

Creato e mantenuto da Vercel, è ampiamente utilizzato per creare applicazioni fullstack avanzate, soprattutto quando è necessario gestire il Server Side Rendering, la Static Site Generation e il routing in modo efficiente.

La sua sintassi chiara e le funzionalità avanzate lo rendono una scelta popolare per lo sviluppo di applicazioni React, adatto a progetti di tutte le dimensioni grazie alla sua scalabilità.

 

Punti di Forza di Next.js:

IMG1.jpg

  • Full Stack: Frontend e Backend nello stesso progetto
  • Routing: Rotte definite con cartelle e file seguendo una nomenclatura speciale
  • SSR: Pre-renderizzazione di default delle pagine sul server (ottimo per la SEO)
  • Ottimizzazioni: Include numerose ottimizzazioni e componenti per migliorare l'esperienza utente

 

Componenti in cerca di ambiente

Con Next.js 14 si ha la possibilità di coinvolgere due ambienti distinti e separati nella realizzazione di una web application: il client e il server.

Storicamente gli sviluppatori hanno sempre dovuto scegliere linguaggi e tecnologie diverse per scrivere codice per i due ambienti. Ad esempio, si può usare Python o C# per il backend, e JavaScript per il frontend (scelta obbligata); o si può usare JavaScript anche nel backend grazie a Node.js, ma rimane sempre un ambiente isolato dal frontend, senza continuità con esso.

Oggi grazie a React e Next è possibile usare lo stesso linguaggio e, soprattutto, lo stesso framework per scrivere componenti per entrambi gli ambienti, evitando complessità aggiuntiva e context switching.

Next.js gestisce due tipi di componenti, la cui elaborazione sarà differente in base all’ambiente in cui si trovano:

  • Server Components: componenti la cui pre-renderizzazione è interamente eseguita sul server, ed il risultato di questa più altre operazioni Node.js, inviato al client quando richiesto

  • Client Components: componenti la cui pre-renderizzazione è parzialmente eseguita sul server, il quale genera una versione placeholder senza logica (solo HTML) che verrà inviata al client quando richiesto. l client eseguirà l’idratazione, ovvero trasforma la versione placeholder e statica della pagina in interattiva, iniettando il JS necessario agli eventi handlers.

⚠️ Importante tenere a mente la differenza tra build-time e request-time:

  • A build time vengono pre-renderizzate sul server le pagine e i componenti con dati statici
  • A request-time quelli con dati dinamici

 

Piacere, Server Component

Con Next.js, prima della versione 14, e specialmente con React Vanilla, siamo abituati ad utilizzare esclusivamente i client components. È evidente, quindi, che la parte più interessante da approfondire siano i server components.

Durante la creazione di un server component, ci troviamo in un ambiente diverso dal browser, ma stiamo comunque scrivendo del backend in Node.js. Possiamo quindi sfruttare tutte le potenzialità del runtime Node.js per svolgere operazioni non possibili nell'ambiente browser, come l'interazione col file system o l'uso di librerie a basso livello.

 

Ecco un esempio di server component. Da notare l’utilizzo di async/await dentro la funzione stessa:

1const BlogPage = async () => {
2  const res = await fetch("https://jsonplaceholder.org/posts");
3  const data: Post[] = await res.json();
4  return (
5    <div style={{ display: "flex", flexDirection: "column", gap: "1rem" }}>
6      {data.map((post) => (
7        <Link key={post.id} href={`/blog/${post.id}`}>
8          {post.title}
9        </Link>
10      ))}
11    </div>
12  );
13};

 

Possiamo specificare in quale ambiente verrà eseguito il componente tramite le direttive “use client” e “use server”, da mettere in cima al componente.

1"use server"
2
3const MyComponent = async () => {
4  //...
5  return <p>Hello</p>
6}
1"use client"
2
3const MyComponent = () => {
4  //...
5  return <p>Hello</p>
6}

 

Benefici dei Server Components

Di default Next.js usa i React Server Components, i quali grazie alla caratteristica di trovarsi sull’ambiente server, godono delle seguenti peculiarità rispetto ai client components:

  • Supporto alle Promises: Utilizzo di async/await piuttosto che combinare hooks come useEffect e useState o librerie esterne per i task asincroni
  • Bundle size del client più snello ed efficace: Spostamento del carico di dati e logica complessa nel server (insieme a grosse dipendenze di terze parti) con l’invio dei soli risultati al client
  • Sicurezza: Non vengono esposti dati sensibili al client
  • Caching: I risultati della UI assemblata dal server sono salvati nel client per essere riutilizzati
  • Metadata: Ottimizzazioni SEO e First Contentful Paint
  • Streaming: Separazione delle pagine e componenti in chunks

 

Quando usare un Client o un Server Component

Ogni ambiente ha le sue funzionalità e limitazioni, quindi il codice per il client e quello per il server saranno differenti, con librerie e dipendenze diverse. Di seguito uno schema riassuntivo su dove ha più senso usare l’uno piuttosto che l’altro:

 

unnamed (1).png

 

Client Component e figli

Una volta dichiarato un Client Component, tutti i suoi children saranno client components, perdendo quindi tutti i benefits di ottimizzazione dei server components.

Una buona pratica sarebbe quella di indicare come client component le foglie dell’albero di rendering.

 

IMG2.jpg

 

I components evidenziati sono client components, mentre gli altri rimangono server components in modo da beneficiare di cache, nessuna fetch a runtime e altre funzionalità che vedremo in seguito.

 

Conclusione

La comprensione di come utilizzare i client e server components in Next.js è fondamentale per sfruttare appieno le potenzialità del framework. Nell'episodio successivo, esploreremo le Server Actions, scoprendo le nuove funzionalità introdotte in Next.js 14 e aprendo a ulteriori possibilità di ottimizzazione e sviluppo.

Autore

Rosario Terranova

Programmatore a tutto tondo, ha avuto esperienza dal mondo dello sviluppo di applicazioni 3D (videogames, virtual reality e augmented reality) al mondo dello sviluppo per il web.

Appassionato di tecnologia e informatica, dopo gli studi ha fatto molteplici esperienze internazionali per poi tornare nella sua amata Sicilia. Lavora principalmente con JavaScript/TypeScript, React.js/Next.js e Node.js lato web, Unity/C#, Unreal Engine e Three.js lato 3D.

Ha a cuore la condivisione delle skills e delle conoscenze, e gli piace dare una mano concreta nelle community.

Devmy su twitterDevmy su linkedinDevmy su link

Contattaci.

Hai un progetto in mente?

Anche se - semplicemente - vuoi prendere un caffè con noi o vedere la nostra collezione di Action Figures scrivici tramite questo form.

Questo sito è protetto da reCAPTCHA e si applicano le Norme sulla privacy e i Termini di servizio di Google.

Ultimi Articoli