A webhely nagyszerű felhasználói élményének biztosításához optimalizálnunk kell az első oldal betöltési idejét és az oldal interakciókra való reagálását. Minél gyorsabban reagál az oldal a felhasználói bevitelre – annál jobb.
Reagálj 18 célja az interaktivitás javítása olyan funkciókkal, mint a szelektív hidratálás val vel Suspense
hogy a hidratálást akadálymentessé tegyük, és nagyobb átláthatóságot biztosítsunk a mi építészeti a választások hatással lesznek alkalmazásunk felhasználói élményére és teljesítményére. A React 18 jelentős teljesítményjavításokat hajt végre, és támogatja a Suspense
a szerveroldali renderelés (SSR) esetén, amely lehetővé teszi az alkalmazások részeinek aszinkron kiszolgálását, az alkalmazás egy lassú részét becsomagolhatja a Suspense összetevőbe, és felszólítja a Reactot, hogy késleltesse a lassú összetevő betöltését.
Reagálj 18 a közelmúltban jelent meg olyan funkciókkal, amelyek az interaktivitás javítását szolgálják. Jellemzők, mint szelektív hidratálás val vel Suspense
hogy a hidratálást akadálymentessé tegyük, és nagyobb átláthatóságot biztosítsunk a mi építészeti a választások hatással lesznek alkalmazásunk felhasználói élményére és teljesítményére. A React 18 támogatást nyújt a következőhöz Suspense
a szerveroldali renderelés (SSR) esetén, amely lehetővé teszi az alkalmazások részeinek aszinkron kiszolgálását, az alkalmazás egy lassú részét becsomagolhatja a Suspense összetevőbe, és felszólítja a Reactot, hogy késleltesse a lassú összetevő betöltését.
A szerveroldali megjelenítés lehetővé teszi, hogy HTML-kódot generáljon a kiszolgálón lévő React összetevőiből, és elküldje azt a felhasználóknak. Az SSR lehetővé teszi a felhasználók számára, hogy láthassák az oldal tartalmát, mielőtt a JavaScript-csomag betöltődik és lefutna, majd a JavaScript-kód betöltődik és egyesül a HTML-kóddal, eseménykezelőket csatolva – ami hidratáció. A hagyományos HTML streaminggel ellentétben ennek nem kell felülről lefelé haladva történnie.
A Suspense
, akkor megmondhatja a Reactnak, hogy először küldje el a többi összetevő HTML-kódját, a helyőrző HTML-kódjával együtt, például egy betöltési pörgetőhöz. Jelentősen javítja a felhasználói élményt és a felhasználó által észlelt késleltetést.
Két fő SSR-funkció van benne A React 18 a Suspense által feloldott:
- HTML streamelése a szerveren.
- Szelektív hidratálás az ügyfélen.
Fedezzük fel React Adatlekérési megközelítések val vel useEffect
és a Suspense
próbálja meg összehasonlítani a backend adatlekérő gyakorlati megoldásokat, esetünkben egy gyors és intuitív fej nélküli CMS-t választunk Kozmikus. Kódpéldáinkat egy link segítségével ellenőrizheti StackBlitz.
Integrációs Cosmic Headless CMS
Adatok lekéréséhez használjuk Kozmikus fej nélküli CMS egy csak háttérben működő tartalomkezelő rendszer (CMS) egy csak háttérben működő tartalomkezelő rendszer (CMS), amely az alapoktól a tartalmat elérhetővé tevő tartalomtárként épül fel. A Cosmic integrálásához és értékeinek lekéréséhez telepítenünk kell a Cosmic modult a projektbe.
npm i cosmicjs
yarn add cosmicjs
Ezután hozzon létre egy ingyenes Cosmic fiók és menj Kozmikus műszerfal Your Bucket > Settings > API Access
és keresse meg a Bucket slug-ját és az API olvasási kulcsát, és adja hozzá őket a Cosmic Fetch funkció létrehozásához fetchDataByType
kérjen a Cosmic vödörbe, és töltse le a létrehozott kategóriák tartalmát Kozmikus lekérdezés típus categories
.
import Cosmic from 'cosmicjs';
const bucket = Cosmic().bucket({
slug: 'your_cosmic_slug',
read_key: 'your_cosmic_read_key',
});
export async function fetchDataByType(objectType = 'categories') {
const params = {
query: {
type: objectType,
},
props: 'title,slug,id,metadata',
sort: '-created_at',
};
try {
const data = await bucket.getObjects(params);
return data.objects;
} catch (error) {
return { error };
}
}
A Cosmic hatékony tartalommodellezési funkciókat is kínál, amelyek lehetővé teszik bármilyen tartalom szupergyors és többcsatornás közzétételét, hogy megvalósítsa az egyszeri létrehozást és a közzétételt mindenhol.
Lehívás a rendereléskor
Lehívás a rendereléskor megközelítés a hálózati kérés magában az összetevőben aktiválódik a beillesztés után, a kérés nem indul el addig, amíg az összetevő meg nem jelenik. Ha nem ír olyan tisztítási függvényt, amely figyelmen kívül hagyja az elavult válaszokat, észre fogja venni a versenyfeltétel (In React) hiba, amikor két kissé eltérő adatkérés történt, és az alkalmazás eltérő eredményt jelenít meg attól függően, hogy melyik kérés fejeződik be először. Valójában a React 18-ban, ha engedélyezi a StrictMode-ot az alkalmazásban, akkor fejlesztői módban megtudhatja, hogy a useEffect használata kétszer lesz meghívva, mert most a React felcsatolja az összetevőt, leválasztja, majd újra felcsatolja, hogy ellenőrizze, hogy a kód megfelelően működik.
Javítsunk ki egy adatlekérési versenyfeltételt, kihasználva a useEffect
tisztító funkció. Ha több kérést is beadunk, de csak az utolsó eredményt jelenítjük meg, használhatunk logikai jelzőt isMount
:
import React, { useEffect, useState } from 'react';
import Category from './components/Category';
import { fetchDataByType } from './cosmic.js';
const App = () => {
const [categories, setCategories] = useState([]);
const getCategories = async () => {
const result = await fetchDataByType('categories');
if (result.length) {
setCategories(result);
}
};
useEffect(() => {
let isMount = true;
if (isMount) {
getCategories();
}
return () => {
isMount = false;
};
}, []);
return (
<div className={cn('container', styles.container)}>
<div className={styles.sidebar}>
<div className={styles.collections}>
{categories?.map((category) => (
<Category key={category.id} info={category} />
))}
</div>
</div>
</div>
);
};
export default App;
Ezen túlmenően, ha egy komponens többször renderelődik (mint általában), az előző effektus törlődik a következő effektus végrehajtása előtt.
Ebben az esetben továbbra is versenyfeltételünk van abban az értelemben, hogy a Cosmic felé több kérés repülés közben lesz, de csak az utolsó eredményét használjuk fel.
Szintén mint Dan Abramov magyarázza, Lehívás a rendereléskor lassú navigációt biztosít a képernyők között. Ha van szülő és gyermek összetevők mindketten bekerülnek useEffects
, akkor a gyermekkomponens el sem tudja kezdeni a letöltést, amíg a szülőkomponens be nem fejezi a letöltést. Az ilyen típusú teljesítményproblémák nagyon gyakoriak az egyoldalas alkalmazásokban, és sokkal több lassúságot okoznak, mint a „túlzott újramegjelenítés”, és ha összetett alkalmazásunk van több párhuzamos kéréssel, akkor az alkalmazás betöltésének különböző részeit véletlenszerű sorrendben látjuk. . Az alkalmazások természetesebb viselkedése az, hogy felülről lefelé jeleníti meg a dolgokat.
Rendering-as-you-fetch
Render-a-you-fetch megközelítés lehetővé teszi, hogy a hálózati kérés elindítása után azonnal megkezdjük a komponensünk renderelését, és nagyjából a hálózati kérés elindítása után azonnal megkezdjük a renderelést.
Suspense az adatlekéréshez
A Suspense használatával nem várjuk meg a választ, mielőtt elkezdjük a renderelést, és a példánk teljes blokkolási idejét (TBT) 106 ms-ról 56 ms-ra csökkentjük.
A React alapvető csapata egyidejű funkciókkal, amelyek megkönnyítik az adatok lekérését a Reactban. Feszültség ezek közé tartozik, és célja, hogy egyszerűsítse a terhelési állapotok kezelését a React komponensekben. Ez egy funkció a React alkalmazás aszinkron műveleteinek kezelésére, és lehetővé teszi a használatát is <Suspense>
deklaratívan „várni” bármi másra, beleértve az adatokat is, és többé nem kell megvárnia az összes JavaScript betöltését, hogy elkezdje hidratálni az oldal egyes részeit.
Először is elindítjuk a hálózati kérést, mielőtt bármely összetevőt az első vonalon megjelenítenénk. Főleg App
komponenst, mindkettőt becsomagoljuk Category
és a Cards
, Main
alkatrészek külön-külön Suspense
alkatrészek a visszaeséseikkel.
Amikor App
először csatlakozik, megpróbálja renderelni Category
és ez kiváltja a resourseCategories.read()
vonal. Ha az adatok még nem állnak készen (azaz a kérés nincs megoldva), akkor a rendszer visszaküldi a Suspense-nek, amely ezután <p>Loading…</p>
. Ugyanez történik a Cards
és a Main
import React, { Suspense } from 'react';
const App = () => {
return (
<main>
<Suspense fallback={<p>Loading.....</p>}>
<Cards />
</Suspense>
<div>
<Suspense fallback={<p>Loading.....</p>}>
<Category />
</Suspense>
</div>
</main>
);
};
export default App;
Suspense
ez nem egy új felület az adatok lekéréséhez, mivel ez a feladat továbbra is olyan könyvtárakra van delegálva, mint a fetch vagy az Axios, és Suspense
Az igazi feladat az, hogy csak annyit mondunk, hogy „betöltés közben mutasd meg ezt a kódot, és mutasd meg, ha kész”, semmi több.
Törölje le a lekérés logikáját wrapPromise.js
Szükségünk van a tördelési lekérés logikájára is, hogy kivételt dobjunk, amikor az összetevőink betöltik az adatokat, vagy az nem sikerült, de egyszerűen visszaadjuk a választ, ha Promise
sikeresen megoldódik, és ha még függőben van, visszavonja az ígéretet.
function wrapPromise(promise) {
let status = 'pending';
let response;
const suspender = promise.then(
res => {
status = 'success';
response = res.objects;
},
err => {
status = 'error';
response = err;
},
);
const handler = {
pending: () => {
throw suspender;
},
error: () => {
throw response;
},
default: () => response,
};
const read = () => {
const result = handler[status] ? handler[status]() :
handler.default();
return result;
};
return { read };
}
export default wrapPromise;
Végén a wrapPromise
függvény ellenőrzi ígéretünk állapotát, majd visszaad egy objektumot, amely tartalmazza a read
metódusként működnek, és ez az, amivel a React komponenseink kölcsönhatásba lépnek az ígéret értékének lekéréséhez.
Most be kell csomagolnunk a kozmikus hívási függvényeket wrapPromise
:
export function fetchDataByType(objectType = 'categories') {
const params = {
query: {
type: objectType,
},
props: 'title,slug,id,metadata',
sort: '-created_at',
};
const data = bucket.getObjects(params);
return wrapPromise(data);
}
A fenti csak egy absztrakció a kozmikus letöltési függvényekhez Suspense
és hozd el egyszer.
Olvassa el az adatokat az összetevőben
Ha minden a dolgok lekérési oldalán van, szeretnénk használni az összetevőnkban. Tehát mi történik, amikor az összetevőt nevezzük a read()
függvény elkezd kivételeket dobni, amíg teljesen fel nem oldódik, és amikor ez megtörténik, folytatja a kód többi részével, esetünkben annak megjelenítésével.
import React from 'react';
import { fetchDataByType } from '../../cosmic.js';
import styles from '../../styles/Collection.module.scss';
const resourseCategories = fetchDataByType();
const Category = () => {
const categories = resourseCategories.read();
const renderCategories = categories?.map((info) => (
<div key={info?.id} className={styles.user}>
<div className={styles.avatar}>
<img
className={styles.image}
src={info?.metadata?.image?.imgix_url}
alt="Avatar"
/>
</div>
<div className={styles.description}>
<div className={styles.name}>{info?.metadata?.title}</div>
<div
className={styles.money}
dangerouslySetInnerHTML={{ __html: info?.content }}
/>
</div>
</div>
));
return <div className={styles.collections}>{renderCategories}</div>;
};
export default Category;
A szülő komponens
Suspense
hozzáférést biztosít a Reactnak az alkalmazásainkban lévő függőben lévő állapotokhoz, és ezért tudja a React, hogy hálózati hívás történik, ez lehetővé teszi számunkra, hogy várakozás közben deklaratívan rendereljünk egy tartalék komponenst.
import React, { Suspense } from 'react';
import Cards from './components/Cards';
import Category from './components/Category';
import Main from './components/Main';
import styles from './styles/Collection.module.scss';
const App = () => {
return (
<div className={styles.wrapper}>
<div className={cn('section-pb', styles.section)}>
<div className={cn('container', styles.container)}>
<div className={styles.row}>
<Suspense fallback={<p>Loading.....</p>}>
<Main />
<Cards />
</Suspense>
</div>
<div className={styles.sidebar}>
<div className={styles.info}>
Collections
<span className={styles.smile} role="img" aria-label="fire">
🔥
</span>
</div>
<Suspense fallback={<p>Loading.....</p>}>
<Category />
</Suspense>
</div>
</div>
</div>
</div>
);
};
export default App;
Következtetés
Most, a Suspense
, az alkalmazást kis, önálló egységekre bonthatja, amelyek az alkalmazás többi része nélkül önmagukban is renderelhetők, így a tartalom még sokkal gyorsabban is elérhetővé válik a felhasználó számára, mint korábban. Összehasonlítás céljából megvizsgáltuk a különféle adatlekérési megközelítéseket.
Próbálja ki saját projektjében, és adja meg visszajelzését. El lehet kezdeni Kozmikus egy gyors CMS-hez, amellyel tesztelheti az adatlekérést Suspense
webhelyekhez és alkalmazásokhoz.