Svenska

Utforska avancerade React-memoiseringstekniker för att optimera prestanda i globala applikationer. Lär dig när och hur du använder React.memo, useCallback, useMemo och mer för att bygga effektiva användargränssnitt.

React Memo: En djupdykning i optimeringstekniker för globala applikationer

React är ett kraftfullt JavaScript-bibliotek för att bygga användargränssnitt, men i takt med att applikationer blir mer komplexa blir prestandaoptimering avgörande. Ett viktigt verktyg i Reacts optimeringsverktygslåda är React.memo. Detta blogginlägg ger en omfattande guide för att förstå och effektivt använda React.memo och relaterade tekniker för att bygga högpresterande React-applikationer för en global publik.

Vad är React.memo?

React.memo är en högre ordningens komponent (HOC) som memoiserar en funktionell komponent. Enkelt uttryckt förhindrar den en komponent från att renderas om ifall dess props inte har ändrats. Som standard gör den en ytlig jämförelse (shallow comparison) av propsen. Detta kan avsevärt förbättra prestandan, särskilt för komponenter som är beräkningsmässigt dyra att rendera eller som renderas om ofta även när deras props förblir desamma.

Tänk dig en komponent som visar en användares profil. Om användarens information (t.ex. namn, avatar) inte har ändrats finns det ingen anledning att rendera om komponenten. React.memo låter dig hoppa över denna onödiga omrendering och sparar därmed värdefull bearbetningstid.

Varför använda React.memo?

Här är de främsta fördelarna med att använda React.memo:

Grundläggande användning av React.memo

Att använda React.memo är enkelt. Omslut helt enkelt din funktionella komponent med det:

import React from 'react';

const MyComponent = (props) => {
 console.log('MyComponent renderad');
 return (
 
{props.data}
); }; export default React.memo(MyComponent);

I detta exempel kommer MyComponent endast att renderas om ifall data-propen ändras. Uttrycket console.log hjälper dig att verifiera när komponenten faktiskt renderas om.

Förstå ytlig jämförelse (Shallow Comparison)

Som standard utför React.memo en ytlig jämförelse av propsen. Det betyder att den kontrollerar om referenserna till propsen har ändrats, inte värdena i sig. Detta är viktigt att förstå när man hanterar objekt och arrayer.

Tänk på följande exempel:

import React, { useState } from 'react';

const MyComponent = (props) => {
 console.log('MyComponent renderad');
 return (
 
{props.data.name}
); }; const MemoizedComponent = React.memo(MyComponent); const App = () => { const [user, setUser] = useState({ name: 'John', age: 30 }); const handleClick = () => { setUser({ ...user }); // Skapar ett nytt objekt med samma värden }; return (
); }; export default App;

I det här fallet, även om värdena i user-objektet (name och age) förblir desamma, skapar handleClick-funktionen en ny objektreferens varje gång den anropas. Därför kommer React.memo att se att data-propen har ändrats (eftersom objektreferensen är annorlunda) och kommer att rendera om MyComponent.

Anpassad jämförelsefunktion

För att hantera problemet med ytlig jämförelse med objekt och arrayer, låter React.memo dig tillhandahålla en anpassad jämförelsefunktion som sitt andra argument. Denna funktion tar två argument: prevProps och nextProps. Den ska returnera true om komponenten *inte* ska renderas om (dvs. propsen är i praktiken desamma) och false om den ska renderas om.

Så här kan du använda en anpassad jämförelsefunktion i föregående exempel:

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

const MyComponent = (props) => {
 console.log('MyComponent renderad');
 return (
 
{props.data.name}
); }; const areEqual = (prevProps, nextProps) => { return prevProps.data.name === nextProps.data.name && prevProps.data.age === nextProps.data.age; }; const MemoizedComponent = memo(MyComponent, areEqual); const App = () => { const [user, setUser] = useState({ name: 'John', age: 30 }); const handleClick = () => { setUser({ ...user }); }; return (
); }; export default App;

I detta uppdaterade exempel jämför areEqual-funktionen egenskaperna name och age i user-objekten. MemoizedComponent kommer nu endast att renderas om ifall antingen name eller age ändras.

När ska man använda React.memo

React.memo är mest effektivt i följande scenarier:

Det är dock viktigt att notera att React.memo inte är en universallösning. Att använda det urskillningslöst kan faktiskt skada prestandan eftersom den ytliga jämförelsen i sig har en kostnad. Därför är det avgörande att profilera din applikation och identifiera de komponenter som skulle dra mest nytta av memoisering.

Alternativ till React.memo

Även om React.memo är ett kraftfullt verktyg är det inte det enda alternativet för att optimera prestandan hos React-komponenter. Här är några alternativ och kompletterande tekniker:

1. PureComponent

För klasskomponenter erbjuder PureComponent liknande funktionalitet som React.memo. Den utför en ytlig jämförelse av både props och state, och renderas endast om om det finns ändringar.

import React from 'react';

class MyComponent extends React.PureComponent {
 render() {
 console.log('MyComponent renderad');
 return (
 
{this.props.data}
); } } export default MyComponent;

PureComponent är ett bekvämt alternativ till att manuellt implementera shouldComponentUpdate, vilket var det traditionella sättet att förhindra onödiga omrenderingar i klasskomponenter.

2. shouldComponentUpdate

shouldComponentUpdate är en livscykelmetod i klasskomponenter som låter dig definiera anpassad logik för att avgöra om en komponent ska renderas om. Den ger mest flexibilitet, men kräver också mer manuellt arbete.

import React from 'react';

class MyComponent extends React.Component {
 shouldComponentUpdate(nextProps, nextState) {
 return nextProps.data !== this.props.data;
 }

 render() {
 console.log('MyComponent renderad');
 return (
 
{this.props.data}
); } } export default MyComponent;

Även om shouldComponentUpdate fortfarande är tillgänglig, föredras i allmänhet PureComponent och React.memo för sin enkelhet och användarvänlighet.

3. useCallback

useCallback är en React-hook som memoiserar en funktion. Den returnerar en memoizerad version av funktionen som endast ändras om en av dess beroenden har ändrats. Detta är särskilt användbart för att skicka callbacks som props till memoizerade komponenter.

Tänk på följande exempel:

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

const MyComponent = (props) => {
 console.log('MyComponent renderad');
 return (
 
 );
};

const MemoizedComponent = memo(MyComponent);

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

 const handleClick = useCallback(() => {
 setCount(count + 1);
 }, [count]);

 return (
 

Antal: {count}

); }; export default App;

I detta exempel säkerställer useCallback att handleClick-funktionen endast ändras när count-statet ändras. Utan useCallback skulle en ny funktion skapas vid varje rendering av App, vilket skulle orsaka att MemoizedComponent renderas om i onödan.

4. useMemo

useMemo är en React-hook som memoiserar ett värde. Den returnerar ett memoizerat värde som endast ändras om ett av dess beroenden har ändrats. Detta är användbart för att undvika dyra beräkningar som inte behöver köras om vid varje rendering.

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

const App = () => {
 const [input, setInput] = useState('');

 const expensiveCalculation = (str) => {
 console.log('Beräknar...');
 let result = 0;
 for (let i = 0; i < str.length * 1000000; i++) {
 result++;
 }
 return result;
 };

 const memoizedResult = useMemo(() => expensiveCalculation(input), [input]);

 return (
 
setInput(e.target.value)} />

Resultat: {memoizedResult}

); }; export default App;

I detta exempel säkerställer useMemo att funktionen expensiveCalculation endast anropas när input-statet ändras. Detta förhindrar att beräkningen körs om vid varje rendering, vilket kan förbättra prestandan avsevärt.

Praktiska exempel för globala applikationer

Låt oss titta på några praktiska exempel på hur React.memo och relaterade tekniker kan tillämpas i globala applikationer:

1. Språkväljare

En språkväljarkomponent renderar ofta en lista över tillgängliga språk. Listan kan vara relativt statisk, vilket innebär att den inte ändras ofta. Att använda React.memo kan förhindra att språkväljaren renderas om i onödan när andra delar av applikationen uppdateras.

import React, { memo } from 'react';

const LanguageItem = ({ language, onSelect }) => {
 console.log(`LanguageItem ${language} renderad`);
 return (
 
  • onSelect(language)}>{language}
  • ); }; const MemoizedLanguageItem = memo(LanguageItem); const LanguageSelector = ({ languages, onSelect }) => { return (
      {languages.map((language) => ( ))}
    ); }; export default LanguageSelector;

    I detta exempel kommer MemoizedLanguageItem endast att renderas om ifall language- eller onSelect-propen ändras. Detta kan vara särskilt fördelaktigt om språklistan är lång eller om onSelect-hanteraren är komplex.

    2. Valutaomvandlare

    En valutaomvandlarkomponent kan visa en lista över valutor och deras växelkurser. Växelkurserna kan uppdateras periodiskt, men listan över valutor kan förbli relativt stabil. Att använda React.memo kan förhindra att valutalistan renderas om i onödan när växelkurserna uppdateras.

    import React, { memo } from 'react';
    
    const CurrencyItem = ({ currency, rate, onSelect }) => {
     console.log(`CurrencyItem ${currency} renderad`);
     return (
     
  • onSelect(currency)}>{currency} - {rate}
  • ); }; const MemoizedCurrencyItem = memo(CurrencyItem); const CurrencyConverter = ({ currencies, onSelect }) => { return (
      {Object.entries(currencies).map(([currency, rate]) => ( ))}
    ); }; export default CurrencyConverter;

    I detta exempel kommer MemoizedCurrencyItem endast att renderas om ifall currency-, rate- eller onSelect-propen ändras. Detta kan förbättra prestandan om valutalistan är lång eller om växelkurserna uppdateras ofta.

    3. Visning av användarprofil

    Att visa en användarprofil innebär att visa statisk information som namn, profilbild och eventuellt en biografi. Att använda `React.memo` säkerställer att komponenten endast renderas om när användardatan faktiskt ändras, inte vid varje uppdatering av föräldrakomponenten.

    import React, { memo } from 'react';
    
    const UserProfile = ({ user }) => {
     console.log('UserProfile renderad');
     return (
     

    {user.name}

    Profil

    {user.bio}

    ); }; export default memo(UserProfile);

    Detta är särskilt användbart om UserProfile är en del av en större, ofta uppdaterad instrumentpanel eller applikation där användardatan i sig inte ändras ofta.

    Vanliga fallgropar och hur man undviker dem

    Även om React.memo är ett värdefullt optimeringsverktyg är det viktigt att vara medveten om vanliga fallgropar och hur man undviker dem:

    Profilering av din applikation

    Det bästa sättet att avgöra om React.memo faktiskt förbättrar prestandan är att profilera din applikation. React tillhandahåller flera verktyg för profilering, inklusive React DevTools Profiler och React.Profiler-API:et.

    React DevTools Profiler låter dig spela in prestandaspårningar av din applikation och identifiera komponenter som renderas om ofta. React.Profiler-API:et låter dig mäta renderingstiden för specifika komponenter programmatiskt.

    Genom att profilera din applikation kan du identifiera de komponenter som skulle dra mest nytta av memoisering och säkerställa att React.memo faktiskt förbättrar prestandan.

    Slutsats

    React.memo är ett kraftfullt verktyg för att optimera prestandan hos React-komponenter. Genom att förhindra onödiga omrenderingar kan det förbättra hastigheten och responsiviteten i dina applikationer, vilket leder till en bättre användarupplevelse. Det är dock viktigt att använda React.memo med omdöme och att profilera din applikation för att säkerställa att den faktiskt förbättrar prestandan.

    Genom att förstå de koncept och tekniker som diskuterats i detta blogginlägg kan du effektivt använda React.memo och relaterade tekniker för att bygga högpresterande React-applikationer för en global publik, och säkerställa att dina applikationer är snabba och responsiva för användare över hela världen.

    Kom ihåg att ta hänsyn till globala faktorer som nätverkslatens och enhetskapacitet när du optimerar dina React-applikationer. Genom att fokusera på prestanda och tillgänglighet kan du skapa applikationer som ger en fantastisk upplevelse för alla användare, oavsett deras plats eller enhet.

    Vidare läsning och resurser