Dansk

Lær hvordan Reacts automatiske batching optimerer flere tilstandsopdateringer, forbedrer applikationsydelsen og forhindrer unødvendige gen-rendereringer. Udforsk eksempler og best practices.

React Automatisk Batching: Optimering af Tilstandsopdateringer for Ydeevne

Reacts ydeevne er afgørende for at skabe glatte og responsive brugergrænseflader. En af de vigtigste funktioner, der er introduceret for at forbedre ydeevnen, er automatisk batching. Denne optimeringsteknik grupperer automatisk flere tilstandsopdateringer i en enkelt gen-renderering, hvilket fører til betydelige ydeevnegevinster. Dette er især relevant i komplekse applikationer med hyppige tilstandsændringer.

Hvad er React Automatisk Batching?

Batching, i forbindelse med React, er processen med at gruppere flere tilstandsopdateringer i en enkelt opdatering. Før React 18 blev batching kun anvendt på opdateringer, der fandt sted inde i React-hændelseshåndterere. Opdateringer uden for hændelseshåndterere, såsom dem inden for setTimeout, promises eller native hændelseshåndterere, blev ikke batchet. Dette kunne føre til unødvendige gen-rendereringer og ydeevneflaskehalse.

React 18 introducerede automatisk batching, som udvider denne optimering til alle tilstandsopdateringer, uanset hvor de forekommer. Det betyder, at uanset om dine tilstandsopdateringer sker inde i en React-hændelseshåndterer, et setTimeout callback eller en promise-opløsning, vil React automatisk batche dem sammen i en enkelt gen-renderering.

Hvorfor er Automatisk Batching Vigtigt?

Automatisk batching giver flere vigtige fordele:

Hvordan Automatisk Batching Fungerer

React opnår automatisk batching ved at forsinke udførelsen af tilstandsopdateringer indtil slutningen af den aktuelle udførelseskontekst. Dette giver React mulighed for at indsamle alle de tilstandsopdateringer, der er sket i løbet af den kontekst, og batche dem sammen i en enkelt opdatering.

Overvej dette forenklede eksempel:

function ExampleComponent() {
  const [count1, setCount1] = useState(0);
  const [count2, setCount2] = useState(0);

  function handleClick() {
    setTimeout(() => {
      setCount1(count1 + 1);
      setCount2(count2 + 1);
    }, 0);
  }

  return (
    <div>
      <p>Count 1: {count1}</p>
      <p>Count 2: {count2}</p>
      <button onClick={handleClick}>Increment</button>
    </div>
  );
}

Før React 18 ville klik på knappen udløse to gen-rendereringer: en for setCount1 og en anden for setCount2. Med automatisk batching i React 18 batches begge tilstandsopdateringer sammen, hvilket resulterer i kun en gen-renderering.

Eksempler på Automatisk Batching i Aktion

1. Asynkrone Opdateringer

Asynkrone operationer, såsom hentning af data fra en API, involverer ofte opdatering af tilstanden, efter at operationen er fuldført. Automatisk batching sikrer, at disse tilstandsopdateringer batches sammen, selvom de forekommer inden for det asynkrone callback.

function DataFetchingComponent() {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    async function fetchData() {
      try {
        const response = await fetch('https://api.example.com/data');
        const jsonData = await response.json();
        setData(jsonData);
        setLoading(false);
      } catch (error) {
        console.error('Error fetching data:', error);
        setLoading(false);
      }
    }

    fetchData();
  }, []);

  if (loading) {
    return <p>Loading...</p>;
  }

  return <div>Data: {JSON.stringify(data)}</div>;
}

I dette eksempel kaldes både setData og setLoading inden for den asynkrone fetchData funktion. React batcher disse opdateringer sammen, hvilket resulterer i en enkelt gen-renderering, når dataene er hentet, og loading-tilstanden er opdateret.

2. Promises

Ligesom asynkrone opdateringer involverer promises ofte opdatering af tilstanden, når promiset opløses eller afvises. Automatisk batching sikrer, at disse tilstandsopdateringer også batches sammen.

function PromiseComponent() {
  const [result, setResult] = useState(null);
  const [error, setError] = useState(null);

  useEffect(() => {
    const myPromise = new Promise((resolve, reject) => {
      setTimeout(() => {
        const success = Math.random() > 0.5;
        if (success) {
          resolve('Promise resolved!');
        } else {
          reject('Promise rejected!');
        }
      }, 1000);
    });

    myPromise
      .then((value) => {
        setResult(value);
        setError(null);
      })
      .catch((err) => {
        setError(err);
        setResult(null);
      });
  }, []);

  if (error) {
    return <p>Error: {error}</p>;
  }

  if (result) {
    return <p>Result: {result}</p>;
  }

  return <p>Loading...</p>;
}

I dette tilfælde kaldes enten setResult og setError(null) ved succes, eller setError og setResult(null) kaldes ved fejl. Uanset hvad vil automatisk batching kombinere disse i en enkelt gen-renderering.

3. Native Hændelseshåndterere

Nogle gange skal du muligvis bruge native hændelseshåndterere (f.eks. addEventListener) i stedet for Reacts syntetiske hændelseshåndterere. Automatisk batching fungerer også i disse tilfælde.

function NativeEventHandlerComponent() {
  const [scrollPosition, setScrollPosition] = useState(0);

  useEffect(() => {
    function handleScroll() {
      setScrollPosition(window.scrollY);
    }

    window.addEventListener('scroll', handleScroll);

    return () => {
      window.removeEventListener('scroll', handleScroll);
    };
  }, []);

  return <p>Scroll Position: {scrollPosition}</p>;
}

Selvom setScrollPosition kaldes inden for en native hændelseshåndterer, vil React stadig batche opdateringerne sammen, hvilket forhindrer overdrevne gen-rendereringer, når brugeren scroller.

Fravælgelse af Automatisk Batching

I sjældne tilfælde kan det være nødvendigt at fravælge automatisk batching. For eksempel kan du tvinge en synkron opdatering for at sikre, at brugergrænsefladen opdateres med det samme. React leverer flushSync API'en til dette formål.

Bemærk: Brug af flushSync bør gøres sparsomt, da det kan påvirke ydeevnen negativt. Det er generelt bedst at stole på automatisk batching, når det er muligt.

import { flushSync } from 'react-dom';

function ExampleComponent() {
  const [count, setCount] = useState(0);

  function handleClick() {
    flushSync(() => {
      setCount(count + 1);
    });
  }

  return (<button onClick={handleClick}>Increment</button>);
}

I dette eksempel tvinger flushSync React til straks at opdatere tilstanden og gen-renderere komponenten, hvilket omgår automatisk batching.

Best Practices for Optimering af Tilstandsopdateringer

Selvom automatisk batching giver betydelige ydeevneforbedringer, er det stadig vigtigt at følge best practices for optimering af tilstandsopdateringer:

Automatisk Batching og Globale Overvejelser

Automatisk batching, der er en central React-ydeevneoptimering, gavner applikationer globalt uanset brugerens placering, netværkshastighed eller enhed. Dens indvirkning kan dog være mere mærkbar i scenarier med langsommere internetforbindelser eller mindre kraftfulde enheder. For internationale målgrupper skal du overveje disse punkter:

Konklusion

React automatisk batching er en kraftfuld optimeringsteknik, der i væsentlig grad kan forbedre ydeevnen af dine React-applikationer. Ved automatisk at gruppere flere tilstandsopdateringer i en enkelt gen-renderering reducerer det renderering overhead, forhindrer inkonsekvente tilstande og fører til en mere jævn og responsiv brugeroplevelse. Ved at forstå, hvordan automatisk batching fungerer, og følge best practices for optimering af tilstandsopdateringer, kan du bygge højtydende React-applikationer, der leverer en fantastisk brugeroplevelse til brugere over hele verden. Udnyttelse af værktøjer som React DevTools hjælper med yderligere at forfine og optimere din applikations ydeevneprofiler i forskellige globale indstillinger.