Lietuvių

Gilus pasinėrimas į „React Flight“ protokolą. Sužinokite, kaip šis serializavimo formatas įgalina „React Server Components“ (RSC), srautinį duomenų perdavimą ir serverio valdomos UI ateitį.

„React Flight“ demistifikavimas: serializuojamas protokolas, suteikiantis galią serverio komponentams

Tinklapių kūrimo pasaulis nuolat evoliucionuoja. Daugelį metų vyraujanti paradigma buvo vieno puslapio aplikacijos (SPA), kai klientui siunčiamas minimalus HTML apvalkalas, kuris vėliau gauna duomenis ir atvaizduoja visą vartotojo sąsają naudodamas „JavaScript“. Nors šis modelis buvo galingas, jis sukėlė iššūkių, tokių kaip dideli paketų dydžiai, kliento-serverio duomenų kriokliai ir sudėtingas būsenos valdymas. Reaguodama į tai, bendruomenė stebi reikšmingą posūkį atgal link į serverį orientuotų architektūrų, tačiau su šiuolaikišku prieskoniu. Šios evoliucijos priešakyje – novatoriška „React“ komandos funkcija: „React“ serverio komponentai (RSC).

Bet kaip šie komponentai, veikiantys išskirtinai serveryje, stebuklingai atsiranda ir sklandžiai integruojasi į kliento pusės aplikaciją? Atsakymas slypi mažiau žinomoje, bet kritiškai svarbioje technologijoje: „React Flight“. Tai nėra API, kurį naudosite tiesiogiai kasdien, tačiau jo supratimas yra raktas į visą šiuolaikinės „React“ ekosistemos potencialą. Šiame įraše pasinersime į „React Flight“ protokolą, demistifikuodami variklį, kuris palaiko naujos kartos tinklo aplikacijas.

Kas yra „React“ serverio komponentai? Trumpas priminimas

Prieš nagrinėdami protokolą, trumpai prisiminkime, kas yra „React“ serverio komponentai ir kodėl jie svarbūs. Skirtingai nuo tradicinių „React“ komponentų, kurie veikia naršyklėje, RSC yra naujo tipo komponentai, skirti vykdyti išskirtinai serveryje. Jie niekada nesiunčia savo „JavaScript“ kodo klientui.

Šis vykdymas tik serveryje suteikia keletą esminių privalumų:

Svarbu atskirti RSC nuo serverio pusės atvaizdavimo (SSR). SSR iš anksto atvaizduoja visą jūsų „React“ aplikaciją į HTML eilutę serveryje. Klientas gauna šį HTML, jį parodo, o tada atsisiunčia visą „JavaScript“ paketą, kad „hidratuotų“ puslapį ir padarytų jį interaktyvų. Priešingai, RSC atvaizduoja į specialų, abstraktų vartotojo sąsajos aprašymą – ne HTML – kuris vėliau srautiniu būdu siunčiamas klientui ir suderinamas su esamu komponentų medžiu. Tai leidžia atlikti daug detalesnį ir efektyvesnį atnaujinimo procesą.

Pristatome „React Flight“: pagrindinis protokolas

Taigi, jei serverio komponentas nesiunčia HTML ar savo „JavaScript“, ką jis siunčia? Štai čia pasirodo „React Flight“. „React Flight“ yra specialiai sukurtas serializavimo protokolas, skirtas perduoti atvaizduotą „React“ komponentų medį iš serverio į klientą.

Galvokite apie tai kaip apie specializuotą, srautiniu būdu perduodamą JSON versiją, kuri supranta „React“ primityvus. Tai yra „laidinis formatas“ (wire format), kuris užpildo atotrūkį tarp jūsų serverio aplinkos ir vartotojo naršyklės. Kai atvaizduojate RSC, „React“ negeneruoja HTML. Vietoj to, jis generuoja duomenų srautą „React Flight“ formatu.

Kodėl tiesiog nenaudoti HTML ar JSON?

Natūralus klausimas: kodėl išradinėti visiškai naują protokolą? Kodėl negalėjome naudoti esamų standartų?

„React Flight“ buvo sukurtas būtent šioms problemoms spręsti. Jis sukurtas būti:

  1. Serializuojamas: Gali atvaizduoti visą komponentų medį, įskaitant atributus (props) ir būseną.
  2. Perduodamas srautu: Vartotojo sąsaja gali būti siunčiama dalimis, leidžiant klientui pradėti atvaizdavimą dar negavus viso atsakymo. Tai yra esminis dalykas integracijai su „Suspense“.
  3. Suprantantis „React“: Jis turi aukščiausio lygio palaikymą „React“ koncepcijoms, tokioms kaip komponentai, kontekstas ir lėtas kliento pusės kodo įkėlimas (lazy-loading).

Kaip veikia „React Flight“: žingsnis po žingsnio

„React Flight“ naudojimo procesas apima suderintą šokį tarp serverio ir kliento. Pereikime per užklausos gyvavimo ciklą programoje, naudojančioje RSC.

Serveryje

  1. Užklausos inicijavimas: Vartotojas pereina į jūsų programos puslapį (pvz., „Next.js App Router“ puslapį).
  2. Komponentų atvaizdavimas: „React“ pradeda atvaizduoti to puslapio serverio komponentų medį.
  3. Duomenų gavimas: Eidamas per medį, jis susiduria su komponentais, kurie gauna duomenis (pvz., `async function MyServerComponent() { ... }`). Jis laukia šių duomenų gavimo.
  4. Serializavimas į „Flight“ srautą: Užuot generavęs HTML, „React“ atvaizdavimo variklis generuoja teksto srautą. Šis tekstas yra „React Flight“ paketas. Kiekviena komponento medžio dalis – `div`, `p`, teksto eilutė, nuoroda į kliento komponentą – yra užkoduojama į specifinį formatą šiame sraute.
  5. Atsakymo perdavimas srautu: Serveris nelaukia, kol bus atvaizduotas visas medis. Kai tik pirmosios vartotojo sąsajos dalys yra paruoštos, jis pradeda siųsti „Flight“ paketą klientui per HTTP. Jei susiduria su „Suspense“ riba, jis siunčia vietos rezervavimo ženklą (placeholder) ir toliau atvaizduoja laikinai sustabdytą turinį fone, o kai jis paruoštas, siunčia jį vėliau tuo pačiu srautu.

Kliento pusėje

  1. Srauto gavimas: „React“ vykdymo aplinka naršyklėje gauna „Flight“ srautą. Tai nėra vienas dokumentas, o nuolatinis instrukcijų srautas.
  2. Analizė ir suderinimas: Kliento pusės „React“ kodas analizuoja „Flight“ srautą dalimis. Tai panašu į brėžinių rinkinio gavimą vartotojo sąsajai kurti ar atnaujinti.
  3. Medžio atkūrimas: Su kiekviena instrukcija „React“ atnaujina savo virtualų DOM. Jis gali sukurti naują `div`, įterpti tekstą arba – svarbiausia – identifikuoti vietos rezervavimo ženklą kliento komponentui.
  4. Kliento komponentų įkėlimas: Kai sraute yra nuoroda į kliento komponentą (pažymėtą direktyva "use client"), „Flight“ pakete yra informacija apie tai, kurį „JavaScript“ paketą atsisiųsti. Tuomet „React“ atsisiunčia tą paketą, jei jis dar nėra talpykloje.
  5. Hidratacija ir interaktyvumas: Kai kliento komponento kodas yra įkeltas, „React“ jį atvaizduoja nurodytoje vietoje ir jį hidratuoja, pridėdamas įvykių klausytojus ir padarydamas jį visiškai interaktyvų. Šis procesas yra labai tikslinis ir vyksta tik interaktyvioms puslapio dalims.

Šis srautinio perdavimo ir selektyvios hidratacijos modelis yra žymiai efektyvesnis už tradicinį SSR modelį, kuris dažnai reikalauja „viskas arba nieko“ viso puslapio hidratacijos.

„React Flight“ paketo anatomija

Norint iš tikrųjų suprasti „React Flight“, naudinga pažvelgti į jo generuojamų duomenų formatą. Nors paprastai tiesiogiai su šiuo neapdorotu išvesties formatu nedirbsite, jo struktūros peržiūra atskleidžia, kaip jis veikia. Paketas yra nauja eilute atskirtų, į JSON panašių eilučių srautas. Kiekviena eilutė arba dalis atspindi tam tikrą informacijos dalį.

Panagrinėkime paprastą pavyzdį. Įsivaizduokime, kad turime tokį serverio komponentą:

app/page.js (Serverio komponentas)

<!-- Tarkime, tai yra kodo blokas tikrame tinklaraštyje --> async function Page() { const userData = await fetchUser(); // Gauna { name: 'Alice' } return ( <div> <h1>Sveiki, {userData.name}</h1> <p>Štai jūsų prietaisų skydelis.</p> <InteractiveButton text="Paspausk mane" /> </div> ); }

Ir kliento komponentą:

components/InteractiveButton.js (Kliento komponentas)

<!-- Tarkime, tai yra kodo blokas tikrame tinklaraštyje --> 'use client'; import { useState } from 'react'; export default function InteractiveButton({ text }) { const [count, setCount] = useState(0); return ( <button onClick={() => setCount(count + 1)}> {text} ({count}) </button> ); }

„React Flight“ srautas, siunčiamas iš serverio klientui šiai vartotojo sąsajai, galėtų atrodyti maždaug taip (supaprastinta aiškumo dėlei):

<!-- Supaprastintas „Flight“ srauto pavyzdys --> M1:{"id":"./components/InteractiveButton.js","chunks":["chunk-abcde.js"],"name":"default"} J0:["$","div",null,{"children":[["$","h1",null,{"children":["Sveiki, ","Alice"]}],["$","p",null,{"children":"Štai jūsų prietaisų skydelis."}],["$","@1",null,{"text":"Paspausk mane"}]]}]

Išnagrinėkime šį paslaptingą išvesties formatą:

Šis paketas yra išsamus instrukcijų rinkinys. Jis tiksliai nurodo klientui, kaip sukonstruoti vartotojo sąsają, kokį statinį turinį rodyti, kur dėti interaktyvius komponentus, kaip įkelti jų kodą ir kokius atributus jiems perduoti. Visa tai atliekama kompaktišku, srautiniu formatu.

Pagrindiniai „React Flight“ protokolo privalumai

„Flight“ protokolo dizainas tiesiogiai įgalina pagrindinius RSC paradigmos privalumus. Supratus protokolą, tampa aišku, kodėl šie privalumai yra įmanomi.

Srautinis perdavimas ir natūralus „Suspense“

Kadangi protokolas yra nauja eilute atskirtas srautas, serveris gali siųsti vartotojo sąsają ją atvaizduojant. Jei komponentas yra laikinai sustabdytas (pvz., laukia duomenų), serveris gali siųsti vietos rezervavimo ženklo instrukciją sraute, nusiųsti likusią puslapio vartotojo sąsają, o tada, kai duomenys bus paruošti, tame pačiame sraute nusiųsti naują instrukciją, kuri pakeis vietos rezervavimo ženklą faktiniu turiniu. Tai suteikia aukščiausios klasės srautinio perdavimo patirtį be sudėtingos kliento pusės logikos.

Nulinis paketo dydis serverio logikai

Žvelgiant į paketą, matyti, kad jame nėra jokio kodo iš paties `Page` komponento. Duomenų gavimo logika, bet kokie sudėtingi verslo skaičiavimai ar priklausomybės, pavyzdžiui, didelės bibliotekos, naudojamos tik serveryje, visiškai neįtraukiamos. Sraute yra tik tos logikos *rezultatas*. Tai yra pagrindinis mechanizmas, slypintis už RSC „nulinio paketo dydžio“ pažado.

Duomenų gavimo kolokacija

`userData` gavimas vyksta serveryje, ir tik jo rezultatas (`'Alice'`) yra serializuojamas į srautą. Tai leidžia kūrėjams rašyti duomenų gavimo kodą tiesiai komponente, kuriam jo reikia – koncepcija, žinoma kaip kolokacija. Šis modelis supaprastina kodą, gerina palaikomumą ir pašalina kliento-serverio krioklius, kurie vargina daugelį SPA.

Selektyvi hidratacija

Protokolo aiškus atskyrimas tarp atvaizduotų HTML elementų ir kliento komponentų nuorodų (`@`) yra tai, kas įgalina selektyvią hidrataciją. Kliento pusės „React“ vykdymo aplinka žino, kad tik `@` komponentams reikia atitinkamo „JavaScript“, kad jie taptų interaktyvūs. Ji gali ignoruoti statines medžio dalis, sutaupydama daug skaičiavimo resursų pradinio puslapio įkėlimo metu.

„React Flight“ palyginimas su alternatyvomis: pasaulinė perspektyva

Norint įvertinti „React Flight“ inovaciją, naudinga jį palyginti su kitais metodais, naudojamais pasaulinėje tinklapių kūrimo bendruomenėje.

Prieš tradicinį SSR + hidrataciją

Kaip minėta, tradicinis SSR siunčia visą HTML dokumentą. Klientas tada atsisiunčia didelį „JavaScript“ paketą ir „hidratuoja“ visą dokumentą, prijungdamas įvykių klausytojus prie statinio HTML. Tai gali būti lėta ir trapu. Viena klaida gali sutrukdyti visam puslapiui tapti interaktyviam. „React Flight“ srautinis ir selektyvus pobūdis yra atsparesnė ir našesnė šios koncepcijos evoliucija.

Prieš GraphQL/REST API

Dažnai kyla painiava, ar RSC pakeičia duomenų API, tokius kaip GraphQL ar REST. Atsakymas yra ne; jie yra papildantys. „React Flight“ yra protokolas vartotojo sąsajos medžio serializavimui, o ne bendros paskirties duomenų užklausų kalba. Iš tiesų, serverio komponentas dažnai naudos GraphQL arba REST API serveryje, kad gautų savo duomenis prieš atvaizdavimą. Pagrindinis skirtumas yra tas, kad šis API iškvietimas vyksta tarp serverių (server-to-server), kas paprastai yra daug greičiau ir saugiau nei kliento-serverio iškvietimas. Klientas gauna galutinę vartotojo sąsają per „Flight“ srautą, o ne neapdorotus duomenis.

Prieš kitas šiuolaikines sistemas

Kitos sistemos pasaulinėje ekosistemoje taip pat sprendžia serverio ir kliento atskirties problemą. Pavyzdžiui:

Praktinis poveikis ir geriausios praktikos kūrėjams

Nors nerašysite „React Flight“ paketų rankiniu būdu, protokolo supratimas padeda suprasti, kaip turėtumėte kurti šiuolaikines „React“ programas.

Naudokite `"use server"` ir `"use client"`

Sistemose kaip „Next.js“, direktyva `"use client"` yra jūsų pagrindinis įrankis kontroliuoti ribą tarp serverio ir kliento. Tai yra signalas kūrimo sistemai, kad komponentas ir jo vaikiniai elementai turėtų būti traktuojami kaip interaktyvi sala. Jo kodas bus supakuotas ir išsiųstas į naršyklę, o „React Flight“ serializuos nuorodą į jį. Priešingai, šios direktyvos nebuvimas (arba `"use server"` naudojimas serverio veiksmams) palieka komponentus serveryje. Įvaldykite šią ribą, kad kurtumėte efektyvias programas.

Mąstykite komponentais, o ne galiniais taškais

Su RSC, pats komponentas gali būti duomenų talpykla. Užuot kūrę API galinį tašką `/api/user` ir kliento pusės komponentą, kuris iš jo gauna duomenis, galite sukurti vieną serverio komponentą ``, kuris duomenis gauna viduje. Tai supaprastina architektūrą ir skatina kūrėjus mąstyti apie vartotojo sąsają ir jos duomenis kaip apie vieną, vientisą vienetą.

Saugumas yra serverio pusės reikalas

Kadangi RSC yra serverio kodas, jie turi serverio privilegijas. Tai galinga, bet reikalauja disciplinuoto požiūrio į saugumą. Visa prieiga prie duomenų, aplinkos kintamųjų naudojimas ir sąveika su vidinėmis paslaugomis vyksta čia. Elkitės su šiuo kodu taip pat griežtai, kaip su bet kuriuo backend API: valykite visas įvestis, naudokite paruoštas užklausas duomenų bazėms ir niekada neatskleiskite jautrių raktų ar paslapčių, kurios galėtų būti serializuotos į „Flight“ paketą.

Naujosios architektūros derinimas

Derinimas RSC pasaulyje keičiasi. Vartotojo sąsajos klaida gali kilti dėl serverio pusės atvaizdavimo logikos arba kliento pusės hidratacijos. Turėsite jaustis patogiai tikrindami tiek savo serverio žurnalus (RSC atveju), tiek naršyklės kūrėjo konsolę (kliento komponentų atveju). „Network“ skirtukas taip pat tampa svarbesnis nei bet kada anksčiau. Galite apžiūrėti neapdorotą „Flight“ atsakymo srautą, kad pamatytumėte, ką tiksliai serveris siunčia klientui, o tai gali būti neįkainojama trikčių šalinimui.

Tinklapių kūrimo ateitis su „React Flight“

„React Flight“ ir jo įgalinta serverio komponentų architektūra yra esminis persvarstymas, kaip kuriame internetui. Šis modelis sujungia geriausias abiejų pasaulių savybes: paprastą, galingą komponentais pagrįstos vartotojo sąsajos kūrimo patirtį ir tradicinių serveryje atvaizduojamų programų našumą bei saugumą.

Šiai technologijai bręstant, galime tikėtis dar galingesnių modelių atsiradimo. Serverio veiksmai (Server Actions), kurie leidžia kliento komponentams iškviesti saugias funkcijas serveryje, yra puikus pavyzdys funkcijos, sukurtos ant šio serverio-kliento komunikacijos kanalo. Protokolas yra išplečiamas, o tai reiškia, kad „React“ komanda ateityje galės pridėti naujų galimybių, nesugadindama pagrindinio modelio.

Išvada

„React Flight“ yra nematomas, tačiau nepakeičiamas „React“ serverio komponentų paradigmos pagrindas. Tai yra labai specializuotas, efektyvus ir srautinis protokolas, kuris paverčia serveryje atvaizduotą komponentų medį instrukcijų rinkiniu, kurį kliento pusės „React“ programa gali suprasti ir naudoti kuriant turtingą, interaktyvią vartotojo sąsają. Perkeldamas komponentus ir jų brangias priklausomybes iš kliento į serverį, jis įgalina greitesnes, lengvesnes ir galingesnes tinklo programas.

Kūrėjams visame pasaulyje supratimas, kas yra „React Flight“ ir kaip jis veikia, nėra tik akademinis pratimas. Jis suteikia esminį mentalinį modelį programų architektūrai, našumo kompromisų darymui ir problemų derinimui šioje naujoje serverio valdomų vartotojo sąsajų eroje. Pokytis vyksta, o „React Flight“ yra protokolas, tiesiantis kelią į priekį.