React Suspensen resurssien dedublikointi: Tuplapyyntöjen estäminen | MLOG | MLOG

Nyt UserResource tarkistaa, onko resurssi jo olemassa cache-objektissa. Jos on, välimuistissa oleva resurssi palautetaan. Muussa tapauksessa käynnistetään uusi pyyntö, ja tuloksena oleva promise tallennetaan välimuistiin. Tämä varmistaa, että kullekin uniikille userId:lle tehdään vain yksi pyyntö.

2. Erillisen välimuistikirjaston käyttö (esim. `lru-cache`)

Monimutkaisemmissa välimuistitustilanteissa kannattaa harkita erillisen välimuistikirjaston, kuten lru-cache tai vastaavan, käyttöä. Nämä kirjastot tarjoavat ominaisuuksia, kuten välimuistin tyhjentämisen vähiten käytetyn (Least Recently Used, LRU) tai muiden periaatteiden mukaan, mikä voi olla ratkaisevan tärkeää muistinkäytön hallinnassa, erityisesti käsiteltäessä suurta määrää resursseja.

Asenna ensin kirjasto:

            
npm install lru-cache

            

Integroi se sitten UserResource-funktioosi:

            
import React, { Suspense } from 'react';
import LRUCache from 'lru-cache';

const fetchUser = (userId) => {
  console.log(`Fetching user with ID: ${userId}`); // Simuloi verkkopyyntöä
  return new Promise(resolve => {
    setTimeout(() => {
      resolve({ id: userId, name: `User ${userId}`, email: `user${userId}@example.com` });
    }, 1000); // Simuloi verkon viivettä
  });
};

const cache = new LRUCache({
  max: 100, // Välimuistin enimmäiskoko (kohteiden määrä)
  ttl: 60000, // Elinaika millisekunteina (1 minuutti)
});

const UserResource = (userId) => {
  if (!cache.has(userId)) {
    let promise = null;
    let status = 'pending'; // odottaa, onnistui, virhe
    let result;

    const suspender = fetchUser(userId).then(
      (r) => {
        status = 'success';
        result = r;
        cache.set(userId, {
          read() {
            return result;
          },
        });
      },
      (e) => {
        status = 'error';
        result = e;
        cache.set(userId, {
          read() {
            throw result;
          },
        });
      }
    );

    cache.set(userId, {
        read() {
            if (status === 'pending') {
                throw suspender;
            } else if (status === 'error') {
                throw result;
            }
            return result;
        }
    });
  }

  return cache.get(userId);
};


const UserProfile = ({ userId }) => {
  const user = UserResource(userId).read();
  return (
    

User Profile

ID: {user.id}

Name: {user.name}

Email: {user.email}

); }; const UserDetails = ({ userId }) => { const user = UserResource(userId).read(); return (

User Details

ID: {user.id}

Name: {user.name}

); }; const App = () => { return ( Loading...
}> ); }; export default App;

Tämä lähestymistapa antaa enemmän hallintaa välimuistin koon ja vanhenemiskäytännön suhteen.

3. Pyyntöjen yhdistäminen (Request Coalescing) kirjastoilla kuten `axios-extensions`

Kirjastot kuten axios-extensions tarjoavat edistyneempiä ominaisuuksia, kuten pyyntöjen yhdistämisen (request coalescing). Pyyntöjen yhdistäminen yhdistää useita identtisiä pyyntöjä yhdeksi pyynnöksi, mikä optimoi verkon käyttöä entisestään. Tämä on erityisen hyödyllistä tilanteissa, joissa pyynnöt tehdään ajallisesti hyvin lähellä toisiaan.

Asenna ensin kirjasto:

            
npm install axios axios-extensions

            

Määritä sitten Axios käyttämään axios-extensions-kirjaston tarjoamaa cache-adapteria.

Esimerkki axios-extensions-kirjaston käytöstä ja resurssin luomisesta:

            
import React, { Suspense } from 'react';
import axios from 'axios';
import { cacheAdapterEnhancer, throttleAdapterEnhancer } from 'axios-extensions';

const instance = axios.create({
  baseURL: 'https://api.example.com', // Korvaa omalla API-päätepisteelläsi
  adapter: cacheAdapterEnhancer(axios.defaults.adapter, { enabledByDefault: true }),
});

const fetchUser = async (userId) => {
  console.log(`Fetching user with ID: ${userId}`); // Simuloi verkkopyyntöä
  const response = await instance.get(`/users/${userId}`);
  return response.data;
};


const UserResource = (userId) => {
    let promise = null;
    let status = 'pending'; // odottaa, onnistui, virhe
    let result;

    const suspender = fetchUser(userId).then(
        (r) => {
            status = 'success';
            result = r;
        },
        (e) => {
            status = 'error';
            result = e;
        }
    );

    return {
        read() {
            if (status === 'pending') {
                throw suspender;
            } else if (status === 'error') {
                throw result;
            }
            return result;
        },
    };
};


const UserProfile = ({ userId }) => {
  const user = UserResource(userId).read();
  return (
    

User Profile

ID: {user.id}

Name: {user.name}

Email: {user.email}

); }; const UserDetails = ({ userId }) => { const user = UserResource(userId).read(); return (

User Details

ID: {user.id}

Name: {user.name}

); }; const App = () => { return ( Loading...
}> ); }; export default App;

Tämä määrittää Axiosin käyttämään välimuistiadapteria, joka tallentaa vastaukset automaattisesti välimuistiin pyynnön konfiguraation perusteella. cacheAdapterEnhancer-funktio tarjoaa vaihtoehtoja välimuistin konfigurointiin, kuten välimuistin enimmäiskoon tai vanhenemisajan asettamisen. throttleAdapterEnhancer-funktiota voidaan myös käyttää rajoittamaan palvelimelle tehtävien pyyntöjen määrää tietyn ajanjakson sisällä, mikä optimoi suorituskykyä entisestään.

Parhaat käytännöt resurssien dedublikointiin

Globaalit näkökohdat datanhaussa ja dedublikoinnissa

Suunniteltaessa datanhakustrategioita globaalille yleisölle, on otettava huomioon useita tekijöitä:

Esimerkiksi globaalille yleisölle suunnattu matkanvaraussivusto voisi käyttää CDN-verkkoa lento- ja hotellisaatavuustietojen tarjoamiseen eri alueilla sijaitsevilta palvelimilta. Sivusto käyttäisi myös valuuttamuunnos-API:a näyttääkseen hinnat käyttäjän paikallisessa valuutassa ja tarjoaisi vaihtoehtoja hakutulosten suodattamiseen kieliasetusten perusteella.

Yhteenveto

Resurssien dedublikointi on olennainen optimointitekniikka React-sovelluksissa, jotka käyttävät Suspensea. Estämällä päällekkäiset datanhakupynnöt voit parantaa merkittävästi suorituskykyä, vähentää palvelimen kuormitusta ja parantaa käyttäjäkokemusta. Valitsitpa sitten yksinkertaisen promise-välimuistin toteuttamisen tai edistyneempien kirjastojen, kuten lru-cache tai axios-extensions, hyödyntämisen, avainasemassa on ymmärtää taustalla olevat periaatteet ja valita ratkaisu, joka parhaiten sopii omiin tarpeisiisi. Muista ottaa huomioon globaalit tekijät, kuten CDN-verkot, lokalisointi ja saavutettavuus, suunnitellessasi datanhakustrategioita monimuotoiselle yleisölle. Toteuttamalla nämä parhaat käytännöt voit rakentaa nopeampia, tehokkaampia ja käyttäjäystävällisempiä React-sovelluksia.