Svenska

En omfattande guide för att optimera prestandan i React-applikationer med useMemo, useCallback och React.memo. Lär dig förhindra onödiga omritningar och förbättra användarupplevelsen.

React Prestandaoptimering: Bemästra useMemo, useCallback och React.memo

React, ett populärt JavaScript-bibliotek för att bygga användargränssnitt, är känt för sin komponentbaserade arkitektur och deklarativa stil. Men när applikationer växer i komplexitet kan prestandan bli ett problem. Onödiga omritningar av komponenter kan leda till trög prestanda och en dålig användarupplevelse. Lyckligtvis tillhandahåller React flera verktyg för att optimera prestandan, inklusive useMemo, useCallback och React.memo. Denna guide går på djupet med dessa tekniker och ger praktiska exempel och handfasta insikter för att hjälpa dig bygga högpresterande React-applikationer.

Förstå omritningar i React

Innan vi dyker in i optimeringsteknikerna är det avgörande att förstå varför omritningar sker i React. När en komponents state eller props ändras, utlöser React en omritning av den komponenten och, potentiellt, dess barnkomponenter. React använder en virtuell DOM för att effektivt uppdatera den faktiska DOM:en, men överdrivna omritningar kan fortfarande påverka prestandan, särskilt i komplexa applikationer. Föreställ dig en global e-handelsplattform där produktpriser uppdateras ofta. Utan optimering kan även en liten prisförändring utlösa omritningar över hela produktlistan, vilket påverkar användarens surfande.

Varför komponenter ritas om

Målet med prestandaoptimering är att förhindra onödiga omritningar och se till att komponenter endast uppdateras när deras data faktiskt har ändrats. Tänk dig ett scenario med realtidsdatavisualisering för aktiemarknadsanalys. Om diagramkomponenterna ritas om i onödan vid varje mindre datauppdatering blir applikationen trög. Att optimera omritningar säkerställer en smidig och responsiv användarupplevelse.

Introduktion till useMemo: Memoisering av kostsamma beräkningar

useMemo är en React-hook som memoiserar resultatet av en beräkning. Memoisering är en optimeringsteknik som lagrar resultaten av kostsamma funktionsanrop och återanvänder dessa resultat när samma indata förekommer igen. Detta förhindrar att funktionen behöver köras om i onödan.

När ska man använda useMemo

Hur useMemo fungerar

useMemo tar två argument:

  1. En funktion som utför beräkningen.
  2. En array av beroenden.

Funktionen exekveras endast när ett av beroendena i arrayen ändras. Annars returnerar useMemo det tidigare memoiserade värdet.

Exempel: Beräkning av Fibonacci-sekvensen

Fibonacci-sekvensen är ett klassiskt exempel på en beräkningsintensiv kalkyl. Låt oss skapa en komponent som beräknar det n:te Fibonacci-talet med hjälp av useMemo.


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

function Fibonacci({ n }) {
  const fibonacciNumber = useMemo(() => {
    console.log('Beräknar Fibonacci...'); // Demonstrerar när beräkningen körs
    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 detta exempel exekveras funktionen calculateFibonacci endast när prop:en n ändras. Utan useMemo skulle funktionen exekveras vid varje omritning av komponenten Fibonacci, även om n förblev detsamma. Föreställ dig att denna beräkning sker på en global finansiell instrumentpanel - varje tick på marknaden orsakar en fullständig omräkning, vilket leder till betydande fördröjning. useMemo förhindrar detta.

Introduktion till useCallback: Memoisering av funktioner

useCallback är en annan React-hook som memoiserar funktioner. Den förhindrar att en ny funktionsinstans skapas vid varje rendering, vilket kan vara särskilt användbart när man skickar callbacks som props till barnkomponenter.

När ska man använda useCallback

Hur useCallback fungerar

useCallback tar två argument:

  1. Funktionen som ska memoriseras.
  2. En array av beroenden.

Funktionen återskapas endast när ett av beroendena i arrayen ändras. Annars returnerar useCallback samma funktionsinstans.

Exempel: Hantera ett knappklick

Låt oss skapa en komponent med en knapp som utlöser en callback-funktion. Vi använder useCallback för att memorisera callback-funktionen.


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

function Button({ onClick, children }) {
  console.log('Knappen ritades om'); // Demonstrerar när knappen ritas om
  return ;
}

const MemoizedButton = React.memo(Button);

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

  const handleClick = useCallback(() => {
    console.log('Knappen klickades');
    setCount((prevCount) => prevCount + 1);
  }, []); // Tom beroendearray innebär att funktionen endast skapas en gång

  return (
    

Antal: {count}

Öka
); } export default App;

I detta exempel skapas funktionen handleClick endast en gång eftersom beroendearrayen är tom. När komponenten App ritas om på grund av state-ändringen i count, förblir funktionen handleClick densamma. Komponenten MemoizedButton, som är omsluten av React.memo, kommer endast att ritas om ifall dess props ändras. Eftersom prop:en onClick (handleClick) förblir densamma, ritas komponenten Button inte om i onödan. Föreställ dig en interaktiv kartapplikation. Varje gång en användare interagerar kan dussintals knappkomponenter påverkas. Utan useCallback skulle dessa knappar ritas om i onödan, vilket skapar en trög upplevelse. Genom att använda useCallback säkerställs en smidigare interaktion.

Introduktion till React.memo: Memoisering av komponenter

React.memo är en högre ordningens komponent (HOC) som memoiserar en funktionell komponent. Den förhindrar komponenten från att ritas om ifall dess props inte har ändrats. Detta liknar PureComponent för klasskomponenter.

När ska man använda React.memo

Hur React.memo fungerar

React.memo omsluter en funktionell komponent och gör en ytlig jämförelse av de föregående och nästa propsen. Om propsen är desamma kommer komponenten inte att ritas om.

Exempel: Visa en användarprofil

Låt oss skapa en komponent som visar en användarprofil. Vi använder React.memo för att förhindra onödiga omritningar om användarens data inte har ändrats.


import React from 'react';

function UserProfile({ user }) {
  console.log('UserProfile ritades om'); // Demonstrerar när komponenten ritas om
  return (
    

Namn: {user.name}

E-post: {user.email}

); } const MemoizedUserProfile = React.memo(UserProfile, (prevProps, nextProps) => { // Egen jämförelsefunktion (valfri) return prevProps.user.id === nextProps.user.id; // Rita endast om ifall användarens ID ändras }); function App() { const [user, setUser] = React.useState({ id: 1, name: 'John Doe', email: 'john.doe@example.com', }); const updateUser = () => { setUser({ ...user, name: 'Jane Doe' }); // Ändrar namnet }; return (
); } export default App;

I detta exempel kommer komponenten MemoizedUserProfile endast att ritas om ifall prop:en user.id ändras. Även om andra egenskaper hos user-objektet ändras (t.ex. namnet eller e-postadressen), kommer komponenten inte att ritas om såvida inte ID:t är annorlunda. Denna anpassade jämförelsefunktion inom `React.memo` möjliggör finkornig kontroll över när komponenten ritas om. Tänk dig en social medieplattform med ständigt uppdaterade användarprofiler. Utan `React.memo` skulle en ändring av en användares status eller profilbild orsaka en fullständig omritning av profilkomponenten, även om de centrala användaruppgifterna förblir desamma. `React.memo` möjliggör riktade uppdateringar och förbättrar prestandan avsevärt.

Kombinera useMemo, useCallback och React.memo

Dessa tre tekniker är mest effektiva när de används tillsammans. useMemo memoiserar kostsamma beräkningar, useCallback memoiserar funktioner och React.memo memoiserar komponenter. Genom att kombinera dessa tekniker kan du avsevärt minska antalet onödiga omritningar i din React-applikation.

Exempel: En komplex komponent

Låt oss skapa en mer komplex komponent som demonstrerar hur man kombinerar dessa tekniker.


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

function ListItem({ item, onUpdate, onDelete }) {
  console.log(`ListItem ${item.id} ritades om`); // Demonstrerar när komponenten ritas om
  return (
    
  • {item.text}
  • ); } const MemoizedListItem = React.memo(ListItem); function List({ items, onUpdate, onDelete }) { console.log('List ritades om'); // Demonstrerar när komponenten ritas om return (
      {items.map((item) => ( ))}
    ); } const MemoizedList = React.memo(List); function App() { const [items, setItems] = useState([ { id: 1, text: 'Objekt 1' }, { id: 2, text: 'Objekt 2' }, { id: 3, text: 'Objekt 3' }, ]); const handleUpdate = useCallback((id) => { setItems((prevItems) => prevItems.map((item) => item.id === id ? { ...item, text: `Uppdaterad ${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 detta exempel:

    Denna kombination av tekniker säkerställer att komponenterna endast ritas om när det är nödvändigt, vilket leder till betydande prestandaförbättringar. Föreställ dig ett storskaligt projekthanteringsverktyg där listor med uppgifter ständigt uppdateras, tas bort och omordnas. Utan dessa optimeringar skulle varje liten ändring i uppgiftslistan utlösa en kaskad av omritningar, vilket gör applikationen långsam och trög. Genom att strategiskt använda useMemo, useCallback och React.memo kan applikationen förbli högpresterande även med komplex data och frekventa uppdateringar.

    Ytterligare optimeringstekniker

    Även om useMemo, useCallback och React.memo är kraftfulla verktyg, är de inte de enda alternativen för att optimera prestanda i React. Här är några ytterligare tekniker att överväga:

    Globala överväganden för optimering

    När man optimerar React-applikationer för en global publik är det viktigt att ta hänsyn till faktorer som nätverkslatens, enheters kapacitet och lokalisering. Här är några tips:

    Slutsats

    Att optimera prestandan i React-applikationer är avgörande för att leverera en smidig och responsiv användarupplevelse. Genom att bemästra tekniker som useMemo, useCallback och React.memo, och genom att överväga globala optimeringsstrategier, kan du bygga högpresterande React-applikationer som skalar för att möta behoven hos en mångsidig användarbas. Kom ihåg att profilera din applikation för att identifiera prestandaflaskhalsar och tillämpa dessa optimeringstekniker strategiskt. Optimera inte i förtid – fokusera på områden där du kan uppnå störst effekt.

    Denna guide ger en solid grund för att förstå och implementera prestandaoptimeringar i React. När du fortsätter att utveckla React-applikationer, kom ihåg att prioritera prestanda och kontinuerligt söka nya sätt att förbättra användarupplevelsen.