Dansk

En omfattende guide til optimering af React-applikationsydeevne ved hjælp af useMemo, useCallback og React.memo. Lær at forhindre unødvendige genrenderinger og forbedre brugeroplevelsen.

React Performanceoptimering: Mestring af useMemo, useCallback og React.memo

React, et populært JavaScript-bibliotek til at bygge brugergrænseflader, er kendt for sin komponentbaserede arkitektur og deklarative stil. Men efterhånden som applikationer vokser i kompleksitet, kan ydeevnen blive en bekymring. Unødvendige genrenderinger af komponenter kan føre til træg ydeevne og en dårlig brugeroplevelse. Heldigvis tilbyder React flere værktøjer til at optimere ydeevnen, herunder useMemo, useCallback og React.memo. Denne guide dykker ned i disse teknikker og giver praktiske eksempler og handlingsrettet indsigt for at hjælpe dig med at bygge højtydende React-applikationer.

Forståelse af React Genrenderinger

Før du dykker ned i optimeringsteknikkerne, er det afgørende at forstå, hvorfor genrenderinger sker i React. Når en komponents tilstand eller props ændres, udløser React en genrendering af den pågældende komponent og potentielt dens underordnede komponenter. React bruger en virtuel DOM til effektivt at opdatere den faktiske DOM, men overdreven genrendering kan stadig påvirke ydeevnen, især i komplekse applikationer. Forestil dig en global e-handelsplatform, hvor produktpriser opdateres hyppigt. Uden optimering kan selv en lille prisændring udløse genrenderinger på tværs af hele produktlisten og påvirke brugernes browsing.

Hvorfor Komponenter Genrenderes

Målet med performanceoptimering er at forhindre unødvendige genrenderinger og sikre, at komponenter kun opdateres, når deres data faktisk er ændret. Overvej et scenarie, der involverer realtidsdatavisualisering til aktiemarkedsanalyse. Hvis diagramkomponenterne genrenderes unødvendigt med hver mindre dataopdatering, vil applikationen blive ubesvaret. Optimering af genrenderinger vil sikre en jævn og responsiv brugeroplevelse.

Introduktion til useMemo: Memoizing af dyre beregninger

useMemo er en React-hook, der memoizes resultatet af en beregning. Memoization er en optimeringsteknik, der gemmer resultaterne af dyre funktionskald og genbruger disse resultater, når de samme input opstår igen. Dette forhindrer behovet for unødvendigt at genudføre funktionen.

Hvornår skal man bruge useMemo

Sådan fungerer useMemo

useMemo tager to argumenter:

  1. En funktion, der udfører beregningen.
  2. Et array af afhængigheder.

Funktionen udføres kun, når en af afhængighederne i arrayet ændres. Ellers returnerer useMemo den tidligere memoized værdi.

Eksempel: Beregning af Fibonacci-sekvensen

Fibonacci-sekvensen er et klassisk eksempel på en beregningsmæssigt intens beregning. Lad os oprette en komponent, der beregner det n'te Fibonacci-tal ved hjælp af useMemo.


import React, { useState, useMemo } from 'react';

function Fibonacci({ n }) {
  const fibonacciNumber = useMemo(() => {
    console.log('Beregner Fibonacci...'); // Viser, hvornår beregningen køres
    function calculateFibonacci(num) {
      if (num <= 1) {
        return num;
      }
      return calculateFibonacci(num - 1) + calculateFibonacci(num - 2);
    }
    return calculateFibonacci(n);
  }, [n]);

  return 

Fibonacci({n}) = {fibonacciNumber}

; } function App() { const [number, setNumber] = useState(5); return (
setNumber(parseInt(e.target.value))} />
); } export default App;

I dette eksempel udføres funktionen calculateFibonacci kun, når n-propen ændres. Uden useMemo ville funktionen blive udført ved hver genrendering af Fibonacci-komponenten, selvom n forblev den samme. Forestil dig denne beregning, der sker på et globalt finansielt dashboard - hver gang markedet ændres, forårsager det en fuld genberegning, hvilket fører til betydelig forsinkelse. useMemo forhindrer det.

Introduktion til useCallback: Memoizing af funktioner

useCallback er en anden React-hook, der memoizes funktioner. Det forhindrer oprettelsen af en ny funktionsforekomst ved hver rendering, hvilket kan være særligt nyttigt, når du sender callbacks som props til underordnede komponenter.

Hvornår skal man bruge useCallback

Sådan fungerer useCallback

useCallback tager to argumenter:

  1. Den funktion, der skal memoizes.
  2. Et array af afhængigheder.

Funktionen genskabes kun, når en af afhængighederne i arrayet ændres. Ellers returnerer useCallback den samme funktionsforekomst.

Eksempel: Håndtering af et knapklik

Lad os oprette en komponent med en knap, der udløser en callback-funktion. Vi bruger useCallback til at memoize callback-funktionen.


import React, { useState, useCallback } from 'react';

function Button({ onClick, children }) {
  console.log('Knap genrenderet'); // Viser, hvornår knappen genrenderes
  return ;
}

const MemoizedButton = React.memo(Button);

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

  const handleClick = useCallback(() => {
    console.log('Knap klikket');
    setCount((prevCount) => prevCount + 1);
  }, []); // Tomt afhængighedsarray betyder, at funktionen kun oprettes én gang

  return (
    

Tæller: {count}

Forøg
); } export default App;

I dette eksempel oprettes funktionen handleClick kun én gang, fordi afhængighedsarrayet er tomt. Når App-komponenten genrenderes på grund af count-tilstandsændringen, forbliver handleClick-funktionen den samme. MemoizedButton-komponenten, der er pakket med React.memo, genrenderes kun, hvis dens props ændres. Fordi onClick-propen (handleClick) forbliver den samme, genrender Button-komponenten ikke unødvendigt. Forestil dig et interaktivt kortprogram. Hver gang en bruger interagerer, kan dusinvis af knapkomponenter blive påvirket. Uden useCallback ville disse knapper unødvendigt genrenderes, hvilket skaber en træg oplevelse. Brug af useCallback sikrer en mere jævn interaktion.

Introduktion til React.memo: Memoizing af komponenter

React.memo er en højere-ordens-komponent (HOC), der memoizes en funktionel komponent. Det forhindrer komponenten i at genrendere, hvis dens props ikke er ændret. Dette svarer til PureComponent for klassiske komponenter.

Hvornår skal man bruge React.memo

Sådan fungerer React.memo

React.memo pakker en funktionel komponent og sammenligner overfladisk de tidligere og næste props. Hvis props er de samme, vil komponenten ikke genrendere.

Eksempel: Vise en brugerprofil

Lad os oprette en komponent, der viser en brugerprofil. Vi bruger React.memo til at forhindre unødvendige genrenderinger, hvis brugerens data ikke er ændret.


import React from 'react';

function UserProfile({ user }) {
  console.log('Brugerprofil genrenderet'); // Viser, hvornår komponenten genrenderes
  return (
    

Navn: {user.name}

Email: {user.email}

); } const MemoizedUserProfile = React.memo(UserProfile, (prevProps, nextProps) => { // Tilpasset sammenligningsfunktion (valgfri) return prevProps.user.id === nextProps.user.id; // Genrender kun, hvis bruger-id'et ændres }); function App() { const [user, setUser] = React.useState({ id: 1, name: 'John Doe', email: 'john.doe@example.com', }); const updateUser = () => { setUser({ ...user, name: 'Jane Doe' }); // Ændring af navnet }; return (
); } export default App;

I dette eksempel vil MemoizedUserProfile-komponenten kun genrendere, hvis user.id-propen ændres. Selvom andre egenskaber for user-objektet ændres (f.eks. navn eller e-mail), vil komponenten ikke genrendere, medmindre id'et er anderledes. Denne tilpassede sammenligningsfunktion inden for React.memo tillader finjusteret kontrol over, hvornår komponenten genrenderes. Overvej en social medieplatform med konstant opdaterede brugerprofiler. Uden React.memo ville ændring af en brugers status eller profilbillede forårsage en fuld genrendering af profilkomponenten, selvom de grundlæggende brugeroplysninger forbliver de samme. React.memo giver mulighed for målrettede opdateringer og forbedrer ydeevnen markant.

Kombinering af useMemo, useCallback og React.memo

Disse tre teknikker er mest effektive, når de bruges sammen. useMemo memoizes dyre beregninger, useCallback memoizes funktioner, og React.memo memoizes komponenter. Ved at kombinere disse teknikker kan du reducere antallet af unødvendige genrenderinger i din React-applikation markant.

Eksempel: En kompleks komponent

Lad os oprette en mere kompleks komponent, der demonstrerer, hvordan man kombinerer disse teknikker.


import React, { useState, useCallback, useMemo } from 'react';

function ListItem({ item, onUpdate, onDelete }) {
  console.log(`ListItem ${item.id} genrenderet`); // Viser, hvornår komponenten genrenderes
  return (
    
  • {item.text}
  • ); } const MemoizedListItem = React.memo(ListItem); function List({ items, onUpdate, onDelete }) { console.log('Liste genrenderet'); // Viser, hvornår komponenten genrenderes return (
      {items.map((item) => ( ))}
    ); } const MemoizedList = React.memo(List); function App() { const [items, setItems] = useState([ { id: 1, text: 'Punkt 1' }, { id: 2, text: 'Punkt 2' }, { id: 3, text: 'Punkt 3' }, ]); const handleUpdate = useCallback((id) => { setItems((prevItems) => prevItems.map((item) => item.id === id ? { ...item, text: `Opdateret ${item.text}` } : item ) ); }, []); const handleDelete = useCallback((id) => { setItems((prevItems) => prevItems.filter((item) => item.id !== id)); }, []); const memoizedItems = useMemo(() => items, [items]); return (
    ); } export default App;

    I dette eksempel:

    Denne kombination af teknikker sikrer, at komponenterne kun genrenderes, når det er nødvendigt, hvilket fører til betydelige ydeevneforbedringer. Forestil dig et storskala projektstyringsværktøj, hvor lister over opgaver konstant opdateres, slettes og ombestilles. Uden disse optimeringer ville enhver lille ændring af opgavelisten udløse en kaskade af genrenderinger, hvilket gør applikationen langsom og ubesvaret. Ved strategisk at bruge useMemo, useCallback og React.memo kan applikationen forblive ydeevneeffektiv, selv med komplekse data og hyppige opdateringer.

    Yderligere optimeringsteknikker

    Selvom useMemo, useCallback og React.memo er kraftfulde værktøjer, er de ikke de eneste muligheder for at optimere React-ydeevnen. Her er et par yderligere teknikker, du kan overveje:

    Globale overvejelser for optimering

    Når du optimerer React-applikationer til et globalt publikum, er det vigtigt at overveje faktorer som netværksforsinkelse, enhedskapacitet og lokalisering. Her er et par tips:

    Konklusion

    Optimering af React-applikationsydeevne er afgørende for at levere en jævn og responsiv brugeroplevelse. Ved at mestre teknikker som useMemo, useCallback og React.memo, og ved at overveje globale optimeringsstrategier, kan du bygge højtydende React-applikationer, der skalerer for at opfylde behovene hos en mangfoldig brugerbase. Husk at profilere din applikation for at identificere ydeevneflaskehalse og anvende disse optimeringsteknikker strategisk. Optimer ikke for tidligt – fokuser på områder, hvor du kan opnå den mest betydningsfulde effekt.

    Denne guide giver et solidt fundament for at forstå og implementere React-performanceoptimeringer. Efterhånden som du fortsætter med at udvikle React-applikationer, skal du huske at prioritere ydeevnen og løbende søge efter nye måder at forbedre brugeroplevelsen.