Un ghid complet pentru regenerarea statică incrementală (ISR) cu Next.js
Publicat: 2022-03-10În urmă cu un an, Next.js 9.3 a lansat suport pentru Static Site Generation (SSG), făcându-l primul cadru hibrid. Eram un utilizator fericit Next.js de aproximativ câțiva ani în acest moment, dar această versiune a făcut din Next.js noua mea soluție implicită. După ce am lucrat intens cu Next.js, m-am alăturat Vercel pentru a ajuta companii precum Tripadvisor și Washington Post pe măsură ce adoptă și scala Next.js.
În acest articol, aș dori să explorez o nouă evoluție a Jamstack: Incremental Static Regeneration (ISR) . Mai jos veți găsi un ghid pentru ISR — inclusiv cazuri de utilizare, demonstrații și compromisuri.
Problema cu generarea de site statice
Ideea din spatele Jamstack-ului este atrăgătoare: pagini statice prestate în prealabil, care pot fi transmise la un CDN și disponibile la nivel global în câteva secunde. Conținutul static este rapid, rezistent la timpi de nefuncționare și indexat imediat de crawler-uri. Dar există unele probleme.
Dacă ați adoptat arhitectura Jamstack în timp ce construiți un site static la scară largă, este posibil să rămâneți blocat să așteptați ore întregi pentru construirea site-ului dvs. Dacă dublezi numărul de pagini, se dublează și timpul de construire. Să luăm în considerare Target.com. Este posibil să generați static milioane de produse cu fiecare implementare?
Chiar dacă fiecare pagină a fost generată static într-un interval de 1 ms nerealist, tot ar dura ore pentru a reconstrui întregul site . Pentru aplicațiile web mari, alegerea unei generații complete de site-uri statice nu este un început. Echipele la scară largă au nevoie de o soluție hibridă, mai flexibilă, personalizată.
Sisteme de management al conținutului (CMS)
Pentru multe echipe, conținutul site-ului lor este decuplat de cod. Utilizarea unui CMS Headless permite editorilor de conținut să publice modificări fără a implica un dezvoltator. Cu toate acestea, cu site-urile statice tradiționale, acest proces poate fi lent.
Luați în considerare un magazin de comerț electronic cu 100.000 de produse. Prețurile produselor se modifică frecvent. Când un editor de conținut modifică prețul căștilor de la 100 USD la 75 USD ca parte a unei promoții, CMS-ul său folosește un webhook pentru a reconstrui întregul site. Nu este fezabil să așteptați ore întregi pentru ca noul preț să fie reflectat.
Build-urile lungi cu calcule inutile ar putea implica, de asemenea, cheltuieli suplimentare. În mod ideal, aplicația dvs. este suficient de inteligentă pentru a înțelege ce produse s-au schimbat și pentru a actualiza progresiv acele pagini fără a fi nevoie de o reconstrucție completă .
Regenerare statică incrementală (ISR)
Next.js vă permite să creați sau să actualizați pagini statice după ce v-ați creat site-ul. Regenerarea statică incrementală (ISR) permite dezvoltatorilor și editorilor de conținut să utilizeze generarea statică pe pagină, fără a fi nevoie să reconstruiască întregul site . Cu ISR, puteți păstra beneficiile statice în timp ce scalați la milioane de pagini.
Paginile statice pot fi generate în timpul execuției (la cerere) și nu în timpul construirii cu ISR. Folosind analize, teste A/B sau alte valori, sunteți dotat cu flexibilitatea de a face propriul compromis în ceea ce privește timpul de construcție.
Luați în considerare magazinul de comerț electronic de înainte cu 100.000 de produse. La o durată realistă de 50 ms pentru a genera static fiecare pagină de produs, acest lucru ar dura aproape 2 ore fără ISR . Cu ISR, putem alege dintre:
- Construiri mai rapide
Generați cele mai populare 1.000 de produse în timpul construirii. Solicitările făcute către alte produse vor fi o pierdere a memoriei cache și vor genera static la cerere: versiuni de 1 minut. - Rată mai mare de accesare a memoriei cache
Generați 10.000 de produse în timpul construirii, asigurându-vă că mai multe produse sunt stocate în cache înainte de solicitarea unui utilizator: versiuni de 8 minute.
Să parcurgem un exemplu de ISR pentru o pagină de produs de comerț electronic.
Noțiuni de bază
Colectare de date
Dacă nu ați mai folosit niciodată Next.js, vă recomand să citiți Noțiuni introductive cu Next.js pentru a înțelege elementele de bază. ISR utilizează același API Next.js pentru a genera pagini statice: getStaticProps
. Specificând revalidate: 60
, informăm Next.js să folosească ISR pentru această pagină.
- Next.js poate defini un timp de revalidare per pagină. Să-l setăm la 60 de secunde.
- Solicitarea inițială către pagina produsului va afișa pagina stocată în cache cu prețul inițial.
- Datele pentru produs sunt actualizate în CMS.
- Orice solicitări către pagină după solicitarea inițială și înainte de 60 de secunde sunt stocate în cache și sunt instantanee.
- După fereastra de 60 de secunde, următoarea solicitare va afișa în continuare pagina stocată în cache (învechită). Next.js declanșează o regenerare a paginii în fundal .
- Odată ce pagina a fost generată cu succes, Next.js va invalida memoria cache și va afișa pagina actualizată a produsului. Dacă regenerarea fundalului eșuează, pagina veche rămâne nemodificată.
// pages/products/[id].js export async function getStaticProps({ params }) { return { props: { product: await getProductFromDatabase(params.id) }, revalidate: 60 } }
Generarea de căi
Next.js definește ce produse să genereze în timpul construirii și care la cerere. Să generăm doar cele mai populare 1.000 de produse în timpul construcției, oferind getStaticPaths
o listă cu primele 1.000 de ID-uri de produs.
Trebuie să configuram modul în care Next.js va „reduce” atunci când solicităm oricare dintre celelalte produse după construirea inițială. Există două opțiuni din care să alegeți: blocking
și true
.
-
fallback: blocking
(de preferat)
Când se face o solicitare către o pagină care nu a fost generată, Next.js va randa pagina pe server la prima solicitare. Cererile viitoare vor servi fișierul static din cache. -
fallback: true
Când se face o solicitare către o pagină care nu a fost generată, Next.js va difuza imediat o pagină statică cu o stare de încărcare la prima solicitare. Când datele se termină de încărcat, pagina va fi redată din nou cu noile date și va fi stocată în cache. Cererile viitoare vor servi fișierul static din cache.
// pages/products/[id].js export async function getStaticPaths() { const products = await getTop1000Products() const paths = products.map((product) => ({ params: { id: product.id } })) return { paths, fallback: 'blocking' } }
Compensații
Next.js se concentrează în primul rând pe utilizatorul final. „Cea mai bună soluție” este relativă și variază în funcție de industrie, public și natura aplicației. Permițând dezvoltatorilor să schimbe între soluții fără a părăsi limitele cadrului, Next.js vă permite să alegeți instrumentul potrivit pentru proiect.
Redare pe partea serverului
ISR nu este întotdeauna soluția potrivită. De exemplu, fluxul de știri Facebook nu poate afișa conținut învechit. În acest caz, ați dori să utilizați SSR și, eventual, propriile antete cache-control
cu chei surogat pentru a invalida conținutul. Deoarece Next.js este un cadru hibrid, puteți face singur acest compromis și puteți rămâne în cadrul cadrului.
// You can cache SSR pages at the edge using Next.js // inside both getServerSideProps and API Routes res.setHeader('Cache-Control', 's-maxage=60, stale-while-revalidate');
SSR și edge caching sunt similare cu ISR (mai ales dacă se utilizează anteturi de cache stale-while-revalidate
), principala diferență fiind prima solicitare. Cu ISR, prima solicitare poate fi garantată statică dacă este pre-rendată. Chiar dacă baza de date scade sau există o problemă de comunicare cu un API, utilizatorii vor vedea în continuare pagina statică difuzată corespunzător. Cu toate acestea, SSR vă va permite să vă personalizați pagina în funcție de cererea primită.
Notă : Utilizarea SSR fără cache poate duce la performanțe slabe. Fiecare milisecundă contează atunci când blocați utilizatorul să vă vadă site-ul, iar acest lucru poate avea un efect dramatic asupra TTFB (Time to First Byte).
Generare statică-site
ISR nu are întotdeauna sens pentru site-urile mici. Dacă perioada de revalidare este mai mare decât timpul necesar pentru reconstruirea întregului site, ați putea la fel de bine să utilizați generarea tradițională de site-uri statice.
Redare pe partea clientului
Dacă utilizați React fără Next.js, utilizați randarea pe partea clientului. Aplicația dvs. servește o stare de încărcare, urmată de solicitarea de date în interiorul JavaScript pe partea client (de exemplu useEffect
). Deși acest lucru vă crește opțiunile de găzduire (deoarece nu este necesar un server), există compromisuri.
Lipsa conținutului pre-redat din HTML inițial duce la optimizarea motorului de căutare (SEO) mai lentă și mai puțin dinamică. De asemenea, nu este posibil să utilizați CSR cu JavaScript dezactivat.
Opțiuni de rezervă ISR
Dacă datele dvs. pot fi preluate rapid, luați în considerare utilizarea fallback: blocking
. Apoi, nu trebuie să luați în considerare starea de încărcare și pagina dvs. va afișa întotdeauna același rezultat (indiferent dacă este sau nu în cache). Dacă preluarea datelor este lentă, fallback: true
vă permite să afișați imediat utilizatorului o stare de încărcare.
ISR: Nu doar stocarea în cache!
Deși am explicat ISR prin contextul unui cache, acesta este conceput pentru a persista paginile dvs. generate între implementări. Aceasta înseamnă că puteți să reveniți instantaneu și să nu vă pierdeți paginile generate anterior.
Fiecare implementare poate fi introdusă printr-un ID, pe care Next.js îl folosește pentru a persista paginile generate static. Când reveniți, puteți actualiza cheia pentru a indica implementarea anterioară, permițând implementări atomice. Aceasta înseamnă că puteți vizita implementările imuabile anterioare și vor funcționa conform intenției.
- Iată un exemplu de revenire a codului cu ISR:
- Împingeți codul și obțineți un ID de implementare 123.
- Pagina ta conține o greșeală de tipar „Smshng Magazine”.
- Actualizați pagina în CMS. Nu este nevoie de reinstalare.
- Odată ce pagina dvs. afișează „Smashing Magazine”, aceasta rămâne în stocare.
- Împingeți un cod prost și implementați ID-ul 345.
- Reveniți la ID-ul de implementare 123.
- Încă vezi „Smashing Magazine”.
Revenirile și paginile statice persistente nu intră în domeniul de aplicare al Next.js și depind de furnizorul dvs. de găzduire. Rețineți că ISR diferă de redarea serverului cu antetele Cache-Control
deoarece, prin proiectare, cache-urile expiră. Acestea nu sunt partajate între regiuni și vor fi eliminate la revenire.
Exemple de regenerare statică incrementală
Regenerarea statică incrementală funcționează bine pentru comerțul electronic, paginile de marketing, postările de blog, mediile susținute de reclame și multe altele.
- Demo de comerț electronic
Next.js Commerce este un kit de pornire all-in-one pentru site-uri de comerț electronic de înaltă performanță. - GitHub Reactions Demo
Reacționați la problema inițială GitHub și urmăriți actualizarea ISR a paginii de destinație generate static. - Tweeturi statice Demo
Acest proiect se implementează în 30 de secunde, dar poate genera static 500 de milioane de tweet-uri la cerere folosind ISR.
Învață Next.js astăzi
Dezvoltatorii și echipele mari aleg Next.js pentru abordarea sa hibridă și capacitatea de a genera progresiv pagini la cerere. Cu ISR, beneficiați de beneficiile statice cu flexibilitatea de redare a serverului. ISR funcționează imediat folosind next start
.
Next.js a fost proiectat pentru adoptare treptată. Cu Next.js, puteți continua să utilizați codul existent și să adăugați cât de mult (sau cât de puțin) React aveți nevoie. Începând mici și adăugând treptat mai multe pagini, puteți preveni funcționarea funcțiilor de deraiere, evitând o rescrie completă. Aflați mai multe despre Next.js - și codare fericită, tuturor!
Lectură suplimentară
- Noțiuni introductive cu Next.js
- Compararea metodelor de stil în Next.js
- Cum se construiește un server GraphQL utilizând rutele API Next.js