Synes Next.js-sider er treige: «Bruker­feil!»

– De siste ukene har jeg sett en del poster om at Next.js-sider oppleves tregt, skriver Marcus Haaland i ukas ForrigeUke, og lurer på hvorfor.

Dette var uka for feilhåndtering og alt-var-bedre-før — og 1504 ting som skjedde i frontendverdenen!

Treghet med server actions

Next.js er stadig verktøyet jeg strekker meg etter, enten det er hobbyprosjekt eller profesjonelt.

Men i de siste ukene har jeg sett en del poster om at Next.js- sider oppleves tregt.

  • En av postene var fra “Documenso”, som skrev appen sin i Next.js, for de åpenbare grunnene med batterier inkludert. Men etter hvert som appen vokste og de tok i bruk React serverkomponenter og server actions, opplevde de problemer med debugging av server actions og bisarre bygg-feil.
  • Også i frontendmiljøet i Bekk har vi diskutert bruken av server actions. Forrige uke var det noen kolleger som sleit med at server actions førte til at navigasjon mellom sider var tregt. Det viste seg at en av årsakene er at server actions kjører sekvensielt, og vil i mellomtiden hindre navigasjon.

Dette er trolig grunnen til at Next.js-dokumentasjonen anbefaler å holde server actions lette — altså å bruke dem kun til muteringer, og ikke til å hente data.

Om du må ha annen funksjonalitet i server actions, kan du flytte funksjonalitet som ikke må skje med engang (som tracing og analytics) i en after-funksjon.

Selv om du bruker server actions riktig, kan du likevel møte på problemer, som vist av denne uløste GitHub-issuen fra mai 2023. Om tipsene over ikke hjelper, så var oppfordringen både fra frontendmiljøet og i Documensos blogg å bruke tRPC. Da slipper du i likhet med server actions å definere API-endepunkter, kan kalle funksjonene du har definert på serveren og du får full typesikkerhet.

...og serverkomponenter

En annen rot til treghet i Next.js- sider har vært React serverkomponenter. Så merkbart var det, at en utvikler mente at han kunne kjenne igjen sider som brukte serverkomponenter:

Utvikler og YouTuber Theo Browne mener derimot at tregheten ikke kommer fra serverkomponentene i seg selv, men heller brukerfeil fra utviklerne. De har rett og slett glemt å oppgi loading state.

Brukere forventer at apper er raske, og når du gjør en handling og ikke får respons, oppleves appen treg og uresponsiv — som kan føre til rageclicks eller at brukeren forlater appen.

Når du laster data i klientsiden, er det lett å huske å gi loading tilstand. For om du prøver å laste data, vil du få typefeil som sier at data kan være udefinert. Derfor laster du data først når loading-staten er ferdig:

function ClientComponent () {
  const { data, loading } = await getData();
 
  if (isLoading) return <Spinner />
 
  return <Component data={data} />
}

Men med serverkomponenter fungerer det annerledes. Komponenten rendres én gang først når alle dataene er ferdig hentet. Du kan altså ikke rendre én gang med spinner, så en gang med dataene. Dette betyr at hele komponenten blokkeres til await-kallet er ferdig, og det gir ingen synlig tilbakemelding til brukeren i mellomtiden:

async function ServerComponent () {
  const { data } = await getData();
 
  return <Component data={data} />
}

For å løse dette må du eksplisitt bruke mekanismer som Next.js sin loading.tsx eller en Suspense-grense for å vise noe mens dataene lastes:

// loading.tsx

function Loading () {
  return <p>Loading ...</p>
}

Siden datahentingen er på serveren, bør hentingen skje raskere enn på klienten. Men om brukeren ikke ser noe endring, føles appen tregere. I videoen forklarer Theo forskjellene på en multi page app og en single page app, og hvordan serverkomponenter havner imellom.

Tradisjonell MPA kan være raskest på å laste nytt innhold, men oppleves tregere av brukeren. Skjermbilde fra Theo Brownes video.
Tradisjonell MPA kan være raskest på å laste nytt innhold, men oppleves tregere av brukeren. Skjermbilde fra Theo Brownes video. Vis mer

Videoen er lang, men innsiktsfull. Ta en titt!

Lysglimt i tregheten

For å bringe litt lys tilbake i Next.js, deler jeg med deg også en utfyllende post om hvordan fem nettsider har fått forbedret ytelsen, også ved bruk av nye React og Next.js-funksjoner.

Osmani og Djirde viser deg hvilken konsekvens trege nettsider har å si. Du får se at når det er snakk om markedsplasser, kan millisekunder virkelig være forskjellen på om et besøk blir til et salg eller noen som bare trykker seg videre.

Forfatterne deler utfordringer og løsninger, og konkluderer dette i syv undertemaer, og gir deg seks bestepraksiser du kan ta med videre:

  1. Måle og optimalisere det som betyr noe: se på første innhold (LCP) og input-forsinkelse (INP) hvis de gjør vondt, og bruk ekte brukerdata for å guide hvor du bør gjøre tiltak.
  2. Ta i bruk nye Next.js- og React-funksjonalitet (som SSR, RSC, Suspense) for bedre ytelse og utvikler-opplevelse.
  3. Cache aggressivt, men forsiktig, og bruk CDN: gi fart på gjentatte besøk, men tenk også over når du bør oppdatere utdatert innhold.
  4. Hold state-håndtering enkelt: ikke bruk Redux eller global state med mindre du trenger det. React Query og context er ofte nok.
  5. Invester i utvikler-verktøy og arkitektur: et velstrukturert prosjekt (som Next sin app-struktur) og raske utvikler-sykluser gir bedre kvalitet.
  6. Tenk UU og UX fra start: bruk semantisk HTML, test med skjermlesere og tenk på loading- og error-tilstander på forhånd.

Om du er nysgjerrig på hvordan de havna på disse seks praksisene, ta en titt på casene her: largeapps.dev/case-studies/advanced

Når React blir eksistensielt

I fjorårets React Conf hadde React-profil Dan Abramov en talk til hensikt å forklare React serverkomponenter, og talken kalte han “React for two computers”. Abramov gikk helt til det grunnleggende, og abstrakte, om hvordan du snakker mellom klient- og serversiden.

Jeg husker jeg hadde noen a-ha øyeblikk under talken — og jeg må innrømme at jeg også hadde en del spørsmålstegn.

Nå har Abramov gitt talken i form av en bloggpost, en slags 2.0 for å utdype poengene hans, men fra den oppfølgende BlueSky-tweeten, har jeg ikke store forventninger om å få spørsmålstegnene oppklart:

I Abramovs neste post lover han å være mer praktisk og du kommer til og med til å forstå hva han snakker om. Skjermbilde av Abramovs bluesky-post: https://bsky.app/profile/danabra.mov/post/3lmostucpq22k
I Abramovs neste post lover han å være mer praktisk og du kommer til og med til å forstå hva han snakker om. Skjermbilde av Abramovs bluesky-post: https://bsky.app/profile/danabra.mov/post/3lmostucpq22k Vis mer

Jeg tror ikke det du får ut av posten er så anvendbart — hvert fall ikke i første omgang. Men det var en del interessante poeng der, som du ikke tenker på i din vanlige hverdag.

Bare i noen av de første avsnittene sammenligner han tags og funksjoner. Har du fundert på at tags kan tenkes på som substantiver, mens funksjoner er verb?

Etter posten har du kanskje oppdatert din mentale modell for serverkomponenter, og kanskje webutvikling og koding generelt.

Så ta en titt på posten. Njutes best med en solo og en kvikklunsj eller to. Også er det ingen skam å snu.

Det var alt for denne gang. Ha en riktig god påske!