Utilizarea cârligelor SWR React cu regenerarea statică incrementală (ISR) Next.js

Publicat: 2022-03-10
Rezumat rapid ↬ Când este asociat cu rutele API ale ISR și Next.js, SWR poate fi folosit pentru a crea o experiență de utilizator receptivă. În acest articol, Sam Poder explică ce este SWR, unde să-l folosești (și unde nu) și cum să construiești un site web utilizând regenerarea statică incrementală.

Dacă ați folosit vreodată regenerarea statică incrementală (ISR) cu Next.js, este posibil să vă fi trezit să trimiteți date învechite către client. Acest lucru se întâmplă atunci când revalidați pagina de pe server. Pentru unele site-uri web funcționează, dar pentru altele (cum ar fi Hack Club's Scrapbook, un site construit de @lachlanjc pe care îl ajut la întreținere), utilizatorul se așteaptă ca datele să fie păstrate la zi.

Prima soluție care îmi vine în minte poate fi pur și simplu randarea paginilor de partea serverului, asigurându-se că clientului i se trimit întotdeauna cele mai actualizate date. Cu toate acestea, preluarea unor bucăți mari de date înainte de randare poate încetini încărcarea inițială a paginii. Soluția folosită în Scrapbook a fost utilizarea bibliotecii SWR a cârligelor React pentru a actualiza pagina stocată în cache de pe server cu preluarea datelor din partea clientului . Această abordare asigură că utilizatorii au în continuare o experiență bună, că site-ul este rapid și că datele sunt ținute la zi.

Faceți cunoștință cu SWR

SWR este o bibliotecă React Hooks construită de Vercel, numele provine de la termenul stale-while-revalidate. După cum sugerează și numele, clientului dvs. vor primi date învechite/vechi, în timp ce cele mai actualizate date sunt preluate (revalidate) prin SWR din partea clientului. SWR nu revalidează datele doar o dată, cu toate acestea, puteți configura SWR să revalideze datele la un interval, atunci când fila își recapătă focalizarea, când un client se reconecta la Internet sau în mod programatic.

Atunci când este asociat cu rutele API ale ISR și Next.js, SWR poate fi folosit pentru a crea o experiență de utilizator receptivă . Clientului i se servește mai întâi pagina generată static în cache (generată cu getStaticProps() ), în fundal serverul începe și procesul de revalidare a paginii respective (citiți mai multe aici). Acest proces se simte rapid pentru client și acum poate vedea setul de date, totuși poate fi puțin depășit. Odată ce pagina este încărcată, se face o solicitare de preluare către o rută API Next.js a dvs., care returnează aceleași date ca cele generate cu getStaticProps() . Când această solicitare este finalizată (presupunând că a avut succes), SWR va actualiza pagina cu aceste date noi.

Să ne uităm acum la Scrapbook și la modul în care aceasta a ajutat la rezolvarea problemei de a avea date învechite pe pagină . Lucrul evident este că acum, clientul primește o versiune actualizată. Lucrul mai interesant este însă impactul asupra vitezei părții noastre. Când măsurăm viteza prin Lighthouse, obținem un indice de viteză de 1,5 secunde pentru varianta ISR + SWR a site-ului și 5,8 secunde pentru varianta Server Side Rendering (plus un avertisment privind timpul de răspuns inițial al serverului). Acesta este un contrast destul de puternic între cele două (și a fost vizibil și la încărcarea paginilor). Dar există și un compromis, pe pagina Server Side Rendered, utilizatorul nu s-a schimbat aspectul site-ului după câteva secunde, cu date noi. Deși cred că Scrapbook gestionează bine această actualizare, este un aspect important atunci când proiectarea experienței utilizatorului dvs.

Mai multe după săritură! Continuați să citiți mai jos ↓

Unde să utilizați SWR (și unde nu)

SWR poate fi instalat într-o varietate de locuri, iată câteva categorii de site-uri în care SWR s-ar potrivi foarte bine:

  • Site-uri cu date live care necesită actualizare într-un ritm rapid.
    Exemple de astfel de site-uri ar fi site-urile de scoruri sportive și de urmărire a zborurilor. Când construiți aceste site-uri, ați căuta să utilizați opțiunea de revalidare la interval cu o setare de interval scăzut (una până la cinci secunde).
  • Site-uri cu un stil de feed de actualizări sau postări care se actualizează în timp real.
    Exemplul clasic în acest sens ar fi site-urile de știri care au bloguri live cu evenimente precum alegerile. Un alt exemplu ar fi și Scrapbook-ul menționat mai sus. În acest caz, probabil că ați dori, de asemenea, să utilizați opțiunea de revalidare la interval, dar cu o setare de interval mai mare (treizeci până la șaizeci de secunde) pentru a economisi utilizarea datelor și pentru a preveni apelurile API inutile.
  • Site-uri cu actualizări de date mai pasive, pe care oamenii le păstrează foarte mult în fundal.
    Exemple de aceste site-uri ar fi paginile meteo sau paginile cu numărul cazurilor COVID-19 din anii 2020. Aceste pagini nu se actualizează la fel de frecvent și, prin urmare, nu au nevoie de revalidarea constantă a celor două exemple anterioare. Cu toate acestea, ar îmbunătăți în continuare experiența utilizatorului pentru actualizarea datelor. În aceste cazuri, aș recomanda revalidarea datei la care fila își recapătă atenția și când un client se reconecta la internet, asta va însemna că dacă o persoană se întoarce cu nerăbdare la robinet în speranța că a existat doar o mică creștere a cazurilor de COVID, va obține rapid acele date.
  • Site-uri cu fragmente mici de date cu care utilizatorii pot interacționa.
    Gândiți-vă la butonul de abonare Youtube, când faceți clic pe abonare, doriți să vedeți că numărul se schimbă și să simțiți că ați făcut diferența. În aceste cazuri, puteți revalida datele în mod programatic folosind SWR pentru a prelua noul număr și a actualiza suma afișată.

Un lucru de remarcat este că toate acestea pot fi aplicate cu sau fără ISR.

Există, desigur, unele locuri în care nu veți dori să utilizați SWR sau să utilizați SWR fără ISR. SWR nu este de mare folos dacă datele dvs. nu se modifică sau se modifică foarte rar și, în schimb, vă poate înfunda solicitările de rețea și vă poate folosi datele utilizatorului mobil. SWR poate funcționa cu pagini care necesită autentificare, cu toate acestea, veți dori să utilizați Server Side Rendering în aceste cazuri și nu Incremental Static Regeneration.

Utilizarea SWR cu Next.js și regenerarea statică incrementală

Acum am explorat teoria acestei strategii, haideți să explorăm cum o punem în practică. Pentru aceasta, vom construi un site web care să arate câte taxiuri sunt disponibile în Singapore (unde locuiesc eu!) folosind acest API furnizat de guvern.

Structura proiectului

Proiectul nostru va funcționa având trei fișiere:

  • lib/helpers.js
  • pages/index.js (fișierul nostru frontend)
  • pages/api/index.js (fișierul nostru API)

Fișierul nostru de asistență va exporta o funcție ( getTaxiData ) care va prelua datele din API-ul extern și apoi le va returna într-un format adecvat pentru uzul nostru. Fișierul nostru API va importa acea funcție și va seta exportul implicit la o funcție de gestionare care va apela funcția getTaxiData și apoi o va returna, aceasta va însemna că trimiterea unei cereri GET către /api va returna datele noastre.

Vom avea nevoie de această abilitate pentru ca SWR să efectueze preluarea datelor de partea clientului. În cele din urmă, în fișierul nostru frontend vom importa getTaxiData și îl vom folosi în getStaticProps , datele sale vor fi transmise funcției implicite de export a fișierului nostru frontend, care va reda pagina noastră React. Facem toate acestea pentru a preveni duplicarea codului și pentru a asigura coerența datelor noastre. Ce gură, să începem acum cu programarea.

Dosarul Helpers

Vom începe prin a crea funcția getTaxiData în lib/helpers.js :

 export async function getTaxiData(){ let data = await fetch("https://api.data.gov.sg/v1/transport/taxi-availability").then(r => r.json()) return {taxis: data.features.properties[0].taxi_count, updatedAt: data.features.properties[0].timestamp} }

Fișierul API

Apoi vom construi funcția de gestionare în api/index.js , precum și vom importa funcția getTaxiData :

 import { getTaxiData } from '../../lib/helpers' export default async function handler(req, res){ res.status(200).json(await getTaxiData()) }

Nu există nimic aici unic pentru SWR sau ISR, în afară de structura de proiect menționată mai sus. Aceste lucruri încep acum în index.js !

Fișierul Front-End

Primul lucru pe care vrem să-l facem este să ne creăm funcția getStaticProps ! Această funcție va importa funcția noastră getTaxiData , o va folosi și apoi va returna datele cu o configurație suplimentară.

 export async function getStaticProps(){ const { getTaxiData } = require("../lib/helpers") return { props: (await getTaxiData()), revalidate: 1 } }

Aș dori să mă concentrez pe cheia de revalidare din obiectul nostru returnat. Această cheie permite practic regenerarea statică incrementală. Îți spune gazdei că la fiecare secundă regenerarea paginii statice este o opțiune disponibilă, acea opțiune este apoi declanșată în fundal atunci când un client vizitează pagina ta. Puteți citi mai multe despre regenerarea statică incrementală (ISR) aici.

Acum este timpul să folosiți SWR! Să-l importăm mai întâi:

 import useSWR from 'swr'

Vom folosi SWR în funcția noastră de redare React, așa că haideți să creăm acea funcție:

 export default function App(props){ }

Primim elementele de recuzită de la getStaticProps . Acum suntem gata să configuram SWR:

 const fetcher = (...args) => fetch(...args).then(res => res.json()) const { data } = useSWR("/api", fetcher, {fallbackData: props, refreshInterval: 30000})

Să descompunem asta. În primul rând, definim fetcher-ul. Acest lucru este cerut de SWR ca argument, astfel încât să știe cum să vă preia datele, având în vedere că diferite cadre etc. pot avea configurații diferite. În acest caz, folosesc funcția furnizată pe pagina de documente SWR. Apoi numim hook-ul useSWR , cu trei argumente: calea de la care să preia datele, funcția fetcher și apoi un obiect opțiuni.

În acel obiect de options , am specificat două lucruri:

  1. Datele de rezervă;
  2. Intervalul la care SWR ar trebui să revalideze datele.

Opțiunea de date de rezervă este locul în care furnizăm datele preluate de la getStaticProps , ceea ce asigură că datele sunt vizibile de la început. În cele din urmă, folosim destructurarea obiectelor pentru a extrage datele din cârlig.

Pentru a finaliza, vom reda acele date cu niște JSX de bază:

 return <div>As of {data.updatedAt}, there are {data.taxis} taxis available in Singapore!</div>

Și, am făcut-o! Acolo avem un exemplu foarte simplu de utilizare a SWR cu regenerare statică incrementală. (Sursa exemplului nostru este disponibilă aici.)

Dacă întâlnești vreodată date învechite cu ISR, știi pe cine să apelezi: SWR.

Citiți suplimentare despre SmashingMag

  • Biblioteca SWR React Hooks
  • O introducere în SWR: React Hooks for Remote Data Fetching, Ibrahima Ndaw
  • ISR vs DPR: Cuvinte mari, explicație rapidă, Cassidy Williams
  • Stilul global vs. local în Next.js, Alexander Dubovoj
  • Rutare pe partea client în Next.js, Adebiyi Adedotun Lukman