πŸ§™β€β™‚οΈβš›οΈπŸš€ Как ΡƒΡΠΊΠΎΡ€ΠΈΡ‚ΡŒ React Π½Π° 300%: Ρ€Π΅Π°Π»ΡŒΠ½Ρ‹ΠΉ кСйс

Π’ΠΈΡ€Ρ‚ΡƒΠ°Π»ΡŒΠ½Ρ‹ΠΉ DOM React – ΠΌΠΎΡ‰Π½Ρ‹ΠΉ инструмСнт, Π½ΠΎ Π½Π΅ волшСбная ΠΏΠ°Π»ΠΎΡ‡ΠΊΠ°. Если Π½Π΅ ΡΠ»Π΅Π΄ΠΈΡ‚ΡŒ Π·Π° Ρ€Π΅Π½Π΄Π΅Ρ€ΠΈΠ½Π³ΠΎΠΌ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ², ΠΌΠΎΠΆΠ½ΠΎ Π»Π΅Π³ΠΊΠΎ ΠΏΡ€Π΅Π²Ρ€Π°Ρ‚ΠΈΡ‚ΡŒ быстроС ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π² Π½Π΅ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚Π»ΠΈΠ²ΠΎΠ³ΠΎ монстра. МногиС ΡΡ‚Π°Π»ΠΊΠΈΠ²Π°ΡŽΡ‚ΡΡ с этим, Π½ΠΎ Π½Π΅ всСгда ΠΏΠΎΠ½ΠΈΠΌΠ°ΡŽΡ‚ ΠΏΡ€ΠΈΡ‡ΠΈΠ½Ρƒ. Π­Ρ‚Π° ΡΡ‚Π°Ρ‚ΡŒΡ ΠΏΠΎΠΌΠΎΠΆΠ΅Ρ‚ Π²Ρ‹ΡΠ²ΠΈΡ‚ΡŒ ΠΈ ΡƒΡΡ‚Ρ€Π°Π½ΠΈΡ‚ΡŒ ΡƒΠ·ΠΊΠΈΠ΅ мСста Π² ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ React-ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ Ρ€Π΅Π°Π»ΡŒΠ½Ρ‹Π΅ кСйсы, практичСскиС ΠΏΡ€ΠΈΠΌΠ΅Ρ€Ρ‹ ΠΈ эффСктивныС инструмСнты для ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΠΈ.

πŸ§™β€β™‚οΈβš›οΈπŸš€ Как ΡƒΡΠΊΠΎΡ€ΠΈΡ‚ΡŒ React Π½Π° 300%: Ρ€Π΅Π°Π»ΡŒΠ½Ρ‹ΠΉ кСйс
ΠžΡ€ΠΈΠ³ΠΈΠ½Π°Π» ΡΡ‚Π°Ρ‚ΡŒΠΈ – Β«React Performance Optimization: Tricks Every Dev Should KnowΒ».

Π’ ΠΏΡ€ΠΎΡˆΠ»ΠΎΠΌ Π³ΠΎΠ΄Ρƒ я сдСлал e-commerce ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ Π·Π°Π³Ρ€ΡƒΠΆΠ°Π»ΠΎΡΡŒ Π·Π° 1,5 сСкунды. Бпустя ΠΏΠΎΠ»Π³ΠΎΠ΄Π°, послС добавлСния ΠΏΠ°Ρ€Ρ‹ Π½ΠΎΠ²Ρ‹Ρ… Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ – динамичСских Ρ„ΠΈΠ»ΡŒΡ‚Ρ€ΠΎΠ² Ρ‚ΠΎΠ²Π°Ρ€ΠΎΠ² ΠΈ Ρ‡Π°Ρ‚Π° – врСмя Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ выросло Π΄ΠΎ 8 сСкунд. ΠŸΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΠΈ пСрСстали ΠΎΠΏΠ»Π°Ρ‡ΠΈΠ²Π°Ρ‚ΡŒ Π·Π°ΠΊΠ°Π·Ρ‹, Π·Π°ΠΊΠ°Π·Ρ‡ΠΈΠΊ ΠΏΡ€ΠΈΡˆΠ΅Π» Π² ΡΡ€ΠΎΡΡ‚ΡŒ. Π§Ρ‚ΠΎ ΠΆΠ΅ стало ΠΏΡ€ΠΈΡ‡ΠΈΠ½ΠΎΠΉ Ρ‚Π°ΠΊΠΎΠ³ΠΎ замСдлСния? НСконтролируСмыС ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π½Ρ‹Π΅ Ρ€Π΅Π½Π΄Π΅Ρ€Ρ‹ ΠΈ ΠΌΠΎΠ½ΠΎΠ»ΠΈΡ‚Π½Ρ‹ΠΉ ΠΊΠΎΠ΄.

React с Π΅Π³ΠΎ Π²ΠΈΡ€Ρ‚ΡƒΠ°Π»ΡŒΠ½Ρ‹ΠΌ DOM – Π½Π΅ волшСбная ΠΏΠ°Π»ΠΎΡ‡ΠΊΠ°. Как любой ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌ, ΠΎΠ½ Ρ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚ рСгулярной ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΠΈ. Π’ этой ΡΡ‚Π°Ρ‚ΡŒΠ΅ Ρ€Π°Π·Π±Π΅Ρ€Π΅ΠΌ:

  • Π‘ΠΊΡ€Ρ‹Ρ‚Ρ‹Π΅ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹ Ρ€Π΅Π½Π΄Π΅Ρ€ΠΈΠ½Π³Π° Π² React (ΠΈ ΠΊΠ°ΠΊ ΠΈΡ… ΠΈΠ·Π±Π΅ΠΆΠ°Ρ‚ΡŒ).
  • Π˜Π½ΡΡ‚Ρ€ΡƒΠΌΠ΅Π½Ρ‚Ρ‹ для Π°ΡƒΠ΄ΠΈΡ‚Π° ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ.
  • ΠžΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΠΈ Π² ΠΊΠΎΠ΄Π΅, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ускорили ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π½Π° 300% (с ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π°ΠΌΠΈ Β«Π΄ΠΎΒ» ΠΈ «послС»).

Как React Ρ€Π΅Π½Π΄Π΅Ρ€ΠΈΡ‚ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹

ΠŸΡ€ΠΈ Ρ€Π°Π±ΠΎΡ‚Π΅ с Π²ΠΈΡ€Ρ‚ΡƒΠ°Π»ΡŒΠ½Ρ‹ΠΌ DOM React отслСТиваСт состояниС прилоТСния. Когда ΠΎΠ½ΠΎ измСняСтся, ΠΎΠ½ сравниваСт Π½ΠΎΠ²Ρ‹ΠΉ Π²ΠΈΡ€Ρ‚ΡƒΠ°Π»ΡŒΠ½Ρ‹ΠΉ DOM со старым ΠΈ обновляСт ΠΈΠ·ΠΌΠ΅Π½Π΅Π½Π½Ρ‹Π΅ части. ΠŸΡ€ΠΈ этом часто React Π·Π°ΠΎΠ΄Π½ΠΎ обновляСт Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ Π½Π΅ Π½ΡƒΠΆΠ½ΠΎ.

НСнуТныС ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π½Ρ‹Π΅ Ρ€Π΅Π½Π΄Π΅Ρ€Ρ‹

Рассмотрим этот ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚:

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

return (
<div>
<button onClick={() => setCount(count + 1)}>Increment</button>
<StaticComponent /> {/* Renders every time count changes! */}
</div>
);
}

function StaticComponent() {
console.log("I'm rendering unnecessarily ");
return <div>I never change!</div>;
}

Π§Ρ‚ΠΎ здСсь происходит? ΠšΠ°ΠΆΠ΄Ρ‹ΠΉ Ρ€Π°Π·, ΠΊΠΎΠ³Π΄Π° наТимаСтся ΠΊΠ½ΠΎΠΏΠΊΠ° Increment, ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π½ΠΎ рСндСрится, хотя ΠΎΠ½ Π²ΠΎΠΎΠ±Ρ‰Π΅ Π½Π΅ зависит ΠΎΡ‚ count. Π£ мСня Π±Ρ‹Π» случай, ΠΊΠΎΠ³Π΄Π° я нСсколько часов ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π» Π΄Π°ΡˆΠ±ΠΎΡ€Π΄, Π° ΠΏΠΎΡ‚ΠΎΠΌ понял, Ρ‡Ρ‚ΠΎ статичСский Ρ„ΡƒΡ‚Π΅Ρ€ рСндСрился 100 Ρ€Π°Π· Π² сСкунду!

Π˜Π½ΡΡ‚Ρ€ΡƒΠΌΠ΅Π½Ρ‚Ρ‹ для поиска ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌ с Ρ€Π΅Π½Π΄Π΅Ρ€ΠΈΠ½Π³ΠΎΠΌ

React DevTools

Как Π²Ρ‹ΡΠ²ΠΈΡ‚ΡŒ лишниС Ρ€Π΅Π½Π΄Π΅Ρ€Ρ‹? ΠŸΠΎΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΠ»Π°Π³ΠΈΠ½ React DevTools для Π±Ρ€Π°ΡƒΠ·Π΅Ρ€Π° Chrome:

  • ΠžΡ‚ΠΊΡ€Ρ‹Π²Π°Π΅ΠΌ DevTools β†’ Π²ΠΊΠ»Π°Π΄ΠΊΠ° Profiler β†’ Start Recording.
  • ВзаимодСйствуСм с ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ΠΌ (ΠΊΠ»ΠΈΠΊΠ°Π΅ΠΌ ΠΏΠΎ ΠΊΠ½ΠΎΠΏΠΊΠ°ΠΌ, ΠΏΠ΅Ρ€Π΅ΠΊΠ»ΡŽΡ‡Π°Π΅ΠΌ страницы).
  • ΠžΡΡ‚Π°Π½Π°Π²Π»ΠΈΠ²Π°Π΅ΠΌ запись ΠΈ Π°Π½Π°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ ΠΎΡ‚Ρ‡Π΅Ρ‚.

ΠžΡ‚Ρ‡Π΅Ρ‚ Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹Π³Π»ΡΠ΄Π΅Ρ‚ΡŒ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π½ΠΎ Ρ‚Π°ΠΊ:

β–² Flamegraph Snapshot (After 3 clicks)
β”œβ”€ App (Root) [Duration: 2.5ms]
β”‚ β”œβ”€ button [Duration: 0.2ms]
β”‚ └─ StaticComponent [Duration: 1.8ms]
β”‚ └─ console.log call
β”œβ”€ App (Root) [Duration: 2.3ms]
β”‚ β”œβ”€ button [Duration: 0.1ms]
β”‚ └─ StaticComponent [Duration: 1.7ms]
β”œβ”€ App (Root) [Duration: 2.6ms]
β”‚ β”œβ”€ button [Duration: 0.2ms]
β”‚ └─ StaticComponent [Duration: 1.9ms]

Π­Ρ‚ΠΎΡ‚ ΠΎΡ‚Ρ‡Π΅Ρ‚ ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ StaticComponent рСндСрился 3 Ρ€Π°Π·Π° Π±Π΅Π· всякой Π½Π° Ρ‚ΠΎ нСобходимости!

πŸ“ŒΠšΠ°ΠΊ Π½Π°ΠΉΡ‚ΠΈ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ½Ρ‹Π΅ мСста? Π˜Ρ‰ΠΈΡ‚Π΅ ΠΎΡ€Π°Π½ΠΆΠ΅Π²Ρ‹Π΅/ΠΆΠ΅Π»Ρ‚Ρ‹Π΅ полосы Π² ΠΏΡ€ΠΎΡ„Π°ΠΉΠ»Π΅Ρ€Π΅ –они ΡƒΠΊΠ°Π·Ρ‹Π²Π°ΡŽΡ‚ Π½Π° ΠΌΠ΅Π΄Π»Π΅Π½Π½Ρ‹Π΅ Ρ€Π΅Π½Π΄Π΅Ρ€Ρ‹. Π’ нашСм случаС StaticComponent засвСтился, ΠΊΠ°ΠΊ новогодняя Π΅Π»ΠΊΠ°.

Как Π»ΠΎΠ³ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π½Π΅Π½ΡƒΠΆΠ½Ρ‹Π΅ Ρ€Π΅Π½Π΄Π΅Ρ€Ρ‹

Для логирования Π½Π΅Π½ΡƒΠΆΠ½Ρ‹Ρ… Ρ€Π΅Ρ€Π΅Π½Π΄Π΅Ρ€ΠΎΠ² достаточно ΡƒΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΡƒ why-did-you-render:

npm install @welldone-software/why-did-you-render

Π—Π°Ρ‚Π΅ΠΌ Π½ΡƒΠΆΠ½ΠΎ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ этот ΠΊΠΎΠ΄ Π² index.js ΠΈΠ»ΠΈ App.js, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π² консоли ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ°Π»ΠΈΡΡŒ прСдупрСТдСния ΠΎ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π°Ρ…, рСндСрящихся Π±Π΅Π· нСобходимости:

import React from 'react';

if (process.env.NODE_ENV !== 'production') {
const whyDidYouRender = require('@welldone-software/why-did-you-render');
whyDidYouRender(React, {
trackAllPureComponents: true, // Shames all components into behaving
});
}

Как-Ρ‚ΠΎ Ρ€Π°Π· эта Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° ΠΏΠΎΠΌΠΎΠ³Π»Π° ΠΌΠ½Π΅ ΠΎΠ±Π½Π°Ρ€ΡƒΠΆΠΈΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ Header постоянно рСрСндСрился ΠΈΠ·-Π·Π° ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° userPreferences, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ обновлялся ΠΏΡ€ΠΈ ΠΊΠ°ΠΆΠ΄ΠΎΠΌ Ρ€Π΅Π½Π΄Π΅Ρ€Π΅. Π˜ΡΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡƒ ΠΏΠΎΠΌΠΎΠ³Π»Π° мСмоизация (Π½ΠΎ ΠΎΠ± этом ΠΏΠΎΠ·ΠΆΠ΅).

***
Π§Ρ‚ΠΎ Ρ‚Π°ΠΊΠΎΠ΅ Frontend Basic ΠΎΡ‚ Proglib Academy?
ΠšΡƒΡ€Ρ Frontend Basic ΠΎΡ‚ Proglib Academy ΠΏΠΎΠΌΠΎΠΆΠ΅Ρ‚ Π²Π°ΠΌ Π·Π° 2 мСсяца ΠΎΡΠ²ΠΎΠΈΡ‚ΡŒ вСрстку Π½Π° HTML/CSS, ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π½Π° JavaScript ΠΈ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ свой ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ ΠΈΠ½Ρ‚Π΅Ρ€Π½Π΅Ρ‚-ΠΌΠ°Π³Π°Π·ΠΈΠ½ Π½Π° React, Π° бСссрочный доступ ΠΊ 26 Π²ΠΈΠ΄Π΅ΠΎΡƒΡ€ΠΎΠΊΠ°ΠΌ ΠΈ обратная связь ΠΎΡ‚ ΠΎΠΏΡ‹Ρ‚Π½Ρ‹Ρ… ΠΏΡ€Π΅ΠΏΠΎΠ΄Π°Π²Π°Ρ‚Π΅Π»Π΅ΠΉ обСспСчат ΠΊΠΎΠΌΡ„ΠΎΡ€Ρ‚Π½ΠΎΠ΅ ΠΎΠ±ΡƒΡ‡Π΅Π½ΠΈΠ΅ Π² ΡƒΠ΄ΠΎΠ±Π½ΠΎΠΌ для вас Ρ‚Π΅ΠΌΠΏΠ΅.

ОснoΠ²Π½Ρ‹Π΅ способы ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΠΈ

React.memo – баунсСр ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ²

React.memo останавливаСт ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π½Ρ‹ΠΉ Ρ€Π΅Π½Π΄Π΅Ρ€ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π°, Ссли Π΅Π³ΠΎ пропсы Π½Π΅ измСнились.

❌ Π”ΠΎ (ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ°):

Π­Ρ‚ΠΎΡ‚ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ рСндСрится ΠΏΡ€ΠΈ ΠΊΠ°ΠΆΠ΄ΠΎΠΌ ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠΈ родитСля, Π΄Π°ΠΆΠ΅ Ссли user остался Ρ‚Π΅ΠΌ ΠΆΠ΅:

<UserProfile user={user} />  {/* Π›ΠΈΡˆΠ½ΠΈΠΉ Ρ€Π΅Ρ€Π΅Π½Π΄Π΅Ρ€! */}

βœ… ПослС (исправлСниС):

React.memo Π·Π°ΠΏΠΎΠΌΠΈΠ½Π°Π΅Ρ‚ ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰Π΅Π΅ значСния пропсов ΠΈ Π½Π΅ Ρ€Π΅Π½Π΄Π΅Ρ€ΠΈΡ‚ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ Π·Π°Π½ΠΎΠ²ΠΎ, Ссли ΠΎΠ½ΠΈ Π½Π΅ измСнились:

const UserProfile = React.memo(({ user }) => {
return <div>{user.name}</div>;
});

βš οΈΠ’Π°ΠΆΠ½Ρ‹ΠΉ нюанс!

React.memo ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ повСрхностноС сравнСниС, ΠΈ Π² случаС с ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°ΠΌΠΈ ΠΈΠ»ΠΈ массивами ΠΌΠΎΠΆΠ΅Ρ‚ Π½Π΅ Π·Π°ΠΌΠ΅Ρ‚ΠΈΡ‚ΡŒ лишний Ρ€Π΅Π½Π΄Π΅Ρ€:

// НС сработаСт, Ссли `user` - это Π½ΠΎΠ²Ρ‹ΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ с Ρ‚Π΅ΠΌΠΈ ΠΆΠ΅ Π΄Π°Π½Π½Ρ‹ΠΌΠΈ
<UserProfile user={{ name: 'Alice' }} />

// Π Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ с ΠΏΡ€ΠΈΠΌΠΈΡ‚ΠΈΠ²Π°ΠΌΠΈ
<UserProfile userId={42} />

Для Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹ Π½ΡƒΠΆΠ½ΠΎ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‚ΡŒ ΠΊΠ°ΡΡ‚ΠΎΠΌΠ½ΡƒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ, которая опрСдСляСт, измСнился Π»ΠΈ пропс:

const UserProfile = React.memo(
({ user }) => <div>{user.name}</div>,
(prevProps, nextProps) => prevProps.user.id === nextProps.user.id
);

Когда ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ React.memo:

  • ΠšΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹ с тяТСлым UI (Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹, Π³Ρ€Π°Ρ„ΠΈΠΊΠΈ).
  • Часто обновляСмыС Ρ€ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΡΠΊΠΈΠ΅ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹ (новостная Π»Π΅Π½Ρ‚Π°, Ρ„ΠΈΠ΄ соцсСти ΠΈ Ρ‚. ΠΏ.)

useCallback ΠΈ useMemo

Π­Ρ‚ΠΈ Π΄Π²Π° Ρ…ΡƒΠΊΠ° ΠΏΠΎΠΌΠΎΠ³Π°ΡŽΡ‚ ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ, прСдотвращая Π½Π΅Π½ΡƒΠΆΠ½Ρ‹Π΅ Ρ€Π΅Ρ€Π΅Π½Π΄Π΅Ρ€Ρ‹ ΠΈ дорогостоящиС вычислСния.

useCallback для прСдотвращСния Π»ΠΈΡˆΠ½ΠΈΡ… Ρ€Π΅Ρ€Π΅Π½Π΄Π΅Ρ€ΠΎΠ² ΠΈΠ·-Π·Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ

Π€ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π² JavaScript ΡΠΎΠ·Π΄Π°ΡŽΡ‚ΡΡ Π·Π°Π½ΠΎΠ²ΠΎ ΠΏΡ€ΠΈ ΠΊΠ°ΠΆΠ΄ΠΎΠΌ Ρ€Π΅Π½Π΄Π΅Ρ€Π΅. Π­Ρ‚ΠΎ ΠΌΠΎΠΆΠ΅Ρ‚ Π²Ρ‹Π·Π²Π°Ρ‚ΡŒ Π½Π΅Π½ΡƒΠΆΠ½Ρ‹Π΅ пСрСрисовки Π΄ΠΎΡ‡Π΅Ρ€Π½ΠΈΡ… ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ².

❌ ΠŸΡ€ΠΈΠΌΠ΅Ρ€ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹ – ΠΊΠ½ΠΎΠΏΠΊΠ° пСрСрисовываСтся ΠΏΡ€ΠΈ ΠΊΠ°ΠΆΠ΄ΠΎΠΌ Ρ€Π΅Π½Π΄Π΅Ρ€Π΅, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ onClickΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ Ρ€Π°Π· ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚ Π½ΠΎΠ²ΡƒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ:

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

  // Новая функция создаСтся ΠΏΡ€ΠΈ ΠΊΠ°ΠΆΠ΄ΠΎΠΌ Ρ€Π΅Π½Π΄Π΅Ρ€Π΅
  const handleClick = () => setCount(count + 1);

  return <Button onClick={handleClick} />;
}

const Button = React.memo(({ onClick }) => {
  return <button onClick={onClick}>Click me</button>;
});

βœ… РСшСниС – useCallback Π·Π°ΠΏΠΎΠΌΠΈΠ½Π°Π΅Ρ‚ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ ΠΈ Π½Π΅ создаСт Π΅Π΅ Π·Π°Π½ΠΎΠ²ΠΎ, Ссли зависимости Π½Π΅ измСнились:

const handleClick = useCallback(() => {
  setCount(prev => prev + 1); // Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ prev, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΈΠ·Π±Π΅ΠΆΠ°Ρ‚ΡŒ зависимостСй
}, []); // ΠŸΡƒΡΡ‚ΠΎΠΉ массив => функция создаСтся ΠΎΠ΄ΠΈΠ½ Ρ€Π°Π·

useMemo для ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΠΈ рСсурсоСмких вычислСний

Если Ρƒ вас Π΅ΡΡ‚ΡŒ ΠΎΠ³Ρ€ΠΎΠΌΠ½Ρ‹ΠΉ список (10 000+ элСмСнтов), ΠΈ Π²Ρ‹ Ρ„ΠΈΠ»ΡŒΡ‚Ρ€ΡƒΠ΅Ρ‚Π΅ Π΅Π³ΠΎ Π½Π° ΠΊΠ°ΠΆΠ΄ΠΎΠ΅ Π½Π°ΠΆΠ°Ρ‚ΠΈΠ΅ клавиши, Π±Π΅Π· useMemo Π½Π΅ ΠΎΠ±ΠΎΠΉΡ‚ΠΈΡΡŒ.

❌ Π‘Π΅Π· useMemo Ρ„ΠΈΠ»ΡŒΡ‚Ρ€Π°Ρ†ΠΈΡ выполняСтся ΠΏΡ€ΠΈ ΠΊΠ°ΠΆΠ΄ΠΎΠΌ Ρ€Π΅Π½Π΄Π΅Ρ€Π΅:

const filteredList = hugeList.filter(item => item.includes(searchTerm));

βœ… Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ useMemo для ΠΊΡΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΡ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π°:

const filteredList = useMemo(() => {
  return hugeList.filter(item => item.includes(searchTerm));
}, [hugeList, searchTerm]); // ΠŸΠ΅Ρ€Π΅ΡΡ‡Π΅Ρ‚ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΏΡ€ΠΈ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΈ зависимостСй
ΠžΡ‚ условного Ρ€Π΅Π½Π΄Π΅Ρ€ΠΈΠ½Π³Π° Π΄ΠΎ дСструктуризации β€” Ρ€Π°Π·Π±ΠΈΡ€Π°Π΅ΠΌ ΠΏΡ€ΠΈΠ΅ΠΌΡ‹, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΡΠ΄Π΅Π»Π°ΡŽΡ‚ ваш ΠΊΠΎΠ΄ Π±ΠΎΠ»Π΅Π΅ ΠΏΡ€ΠΎΡ„Π΅ΡΡΠΈΠΎΠ½Π°Π»ΡŒΠ½Ρ‹ΠΌ ΠΈ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅ΠΌΡ‹ΠΌ.

ΠžΡ‚Π»ΠΎΠΆΠ΅Π½Π½Π°Ρ ΠΈ фоновая Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠ°

На Π³Π»Π°Π²Π½ΠΎΠΉ страницС ΡƒΠΆΠ΅ упомянутого ΠΌΠ΅Π΄Π»Π΅Π½Π½ΠΎΠ³ΠΎ прилоТСния Π½Π°Ρ…ΠΎΠ΄ΠΈΠ»Π°ΡΡŒ увСсистая ΠΊΠ°Ρ€ΡƒΡΠ΅Π»ΡŒ, ΠΈ этот ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ загруТался Π΄Π°ΠΆΠ΅ для Ρ‚Π΅Ρ… ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΏΠΎΠΊΠΈΠ΄Π°Π»ΠΈ сайт ΠΏΠΎΡ‡Ρ‚ΠΈ сразу. Π’Π°ΠΊΠΈΠ΅ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹, разумССтся, Π½ΡƒΠΆΠ½ΠΎ Π·Π°Π³Ρ€ΡƒΠΆΠ°Ρ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‚ΠΎΠ³Π΄Π°, ΠΊΠΎΠ³Π΄Π° ΠΎΠ½ΠΈ Π΄Π΅ΠΉΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ Π½ΡƒΠΆΠ½Ρ‹.

Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ React.lazy для динамичСской ΠΏΠΎΠ΄Π³Ρ€ΡƒΠ·ΠΊΠΈ:

const ProductCarousel = React.lazy(() => import('./ProductCarousel'));

function HomePage() {
  return (
    <div>
      <HeroBanner />
      <Suspense fallback={<Spinner />}>
        <ProductCarousel />  {/* ЗагруТаСтся Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΏΡ€ΠΈ Ρ€Π΅Π½Π΄Π΅Ρ€Π΅ */}
      </Suspense>
    </div>
  );
}

МоТно ΠΏΡ€Π΅Π΄Π²Π°Ρ€ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ Π·Π°Π³Ρ€ΡƒΠ·ΠΈΡ‚ΡŒ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ Π² Ρ„ΠΎΠ½ΠΎΠ²ΠΎΠΌ Ρ€Π΅ΠΆΠΈΠΌΠ΅, ΠΊΠΎΠ³Π΄Π° ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚ Π½ΠΈΠ·ΠΊΡƒΡŽ Π°ΠΊΡ‚ΠΈΠ²Π½ΠΎΡΡ‚ΡŒ:

const ProductCarousel = React.lazy(() => import(
  /* webpackPrefetch: true */ './ProductCarousel'
));

НСбольшой минус – ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ ΠΌΠΎΠΆΠ΅Ρ‚ Π½Π° ΠΌΠ³Π½ΠΎΠ²Π΅Π½ΠΈΠ΅ ΡƒΠ²ΠΈΠ΄Π΅Ρ‚ΡŒ спиннСр ΠΏΡ€ΠΈ ΠΌΠ΅Π΄Π»Π΅Π½Π½ΠΎΠΌ соСдинСнии (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, 3G).

Π”ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Π°Ρ оптимизация: Context API ΠΈ Ρ€Π°Π±ΠΎΡ‚Π° с большими списками

Context API – Π½Π΅Π·Π°ΠΌΠ΅Ρ‚Π½Ρ‹ΠΉ ΡƒΠ±ΠΈΠΉΡ†Π° ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ

Π€Π°Ρ‚Π°Π»ΡŒΠ½Π°Ρ ошибка – Ρ…Ρ€Π°Π½ΠΈΡ‚ΡŒ Π² AppContext ΠΈ Π΄Π°Π½Π½Ρ‹Π΅ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ, ΠΈ Ρ‚Π΅ΠΌΡƒ оформлСния, ΠΈ увСдомлСния. ΠŸΡ€ΠΈ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΈ Ρ‚Π΅ΠΌΡ‹, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Π±ΡƒΠ΄ΡƒΡ‚ ΠΏΠ΅Ρ€Π΅Ρ€ΠΈΡΠΎΠ²Ρ‹Π²Π°Ρ‚ΡŒΡΡ всС ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‰ΠΈΠ΅ контСкст, Π΄Π°ΠΆΠ΅ Ссли ΠΎΠ½ΠΈ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π΄Π°Π½Π½Ρ‹Π΅ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ. ΠŸΡ€Π°Π²ΠΈΠ»ΡŒΠ½Ρ‹ΠΉ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ – Ρ€Π°Π·Π΄Π΅Π»ΠΈΡ‚ΡŒ контСксты ΠΈ ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Ρ‚ΡŒ ΠΈΡ… ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎ:

<UserContext.Provider value={user}>
  <ThemeContext.Provider value={theme}>
    <App />
  </ThemeContext.Provider>
</UserContext.Provider>

ИзмСнСниС theme заставит Ρ€Π΅Ρ€Π΅Π½Π΄Π΅Ρ€ΠΈΡ‚ΡŒΡΡ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‰ΠΈΠ΅ ThemeContext.

ΠžΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΡ Π±ΠΎΠ»ΡŒΡˆΠΈΡ… списков

ΠŸΡ€ΠΈ Ρ€Π΅Π½Π΄Π΅Ρ€ΠΈΠ½Π³Π΅ списка ΠΈΠ· 10 000 элСмСнтов Π±Ρ€Π°ΡƒΠ·Π΅Ρ€ создаeΡ‚ 10 000 DOM-ΡƒΠ·Π»ΠΎΠ². Π­Ρ‚ΠΎ Π·Π°Π³Ρ€ΡƒΠΆΠ°Π΅Ρ‚ процСссор, замСдляСт ΠΏΡ€ΠΎΠΊΡ€ΡƒΡ‚ΠΊΡƒ ΠΈ ΠΌΠΎΠΆΠ΅Ρ‚ привСсти ΠΊ зависанию прилоТСния Π½Π° слабых Π³Π°Π΄ΠΆΠ΅Ρ‚Π°Ρ…. Π Π΅ΡˆΠΈΡ‚ΡŒ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡƒ ΠΏΠΎΠΌΠΎΠΆΠ΅Ρ‚ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° react-window, которая Ρ€Π΅Π½Π΄Π΅Ρ€ΠΈΡ‚ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π²ΠΈΠ΄ΠΈΠΌΡ‹Π΅ элСмСнты, Π° Π½Π΅ вСсь список:

import { FixedSizeList as List } from 'react-window';

const Row = ({ index, style }) => (
  <div style={style}>Item {data[index]}</div>
);

function BigList() {
  return (
    <List
      height={400}       // Высота области списка
      itemCount={10000}  // ВсСго 10 000 элСмСнтов
      itemSize={50}      // Высота ΠΎΠ΄Π½ΠΎΠ³ΠΎ элСмСнта
      width={300}        // Π¨ΠΈΡ€ΠΈΠ½Π° списка
    >
      {Row}
    </List>
  );
}

Π Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚: количСство DOM-ΡƒΠ·Π»ΠΎΠ² сокращаСтся с 10 000 Π΄ΠΎ максимум 20 (Π² Π·ΠΎΠ½Π΅ видимости), CPU Π½Π΅ пСрСгруТаСтся, Π»Π°Π³ΠΈ ΠΈΡΡ‡Π΅Π·Π°ΡŽΡ‚, ΠΏΡ€ΠΎΠΊΡ€ΡƒΡ‚ΠΊΠ° становится ΠΏΠ»Π°Π²Π½ΠΎΠΉ.

Π Π΅Π°Π»ΡŒΠ½Ρ‹ΠΉ кСйс: оптимизация поиска Π² ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΈ для бронирования ΠΏΡƒΡ‚Π΅ΡˆΠ΅ΡΡ‚Π²ΠΈΠΉ

ΠŸΠ»Π°Ρ‚Ρ„ΠΎΡ€ΠΌΠ° для бронирования ΠΏΡƒΡ‚Π΅ΡˆΠ΅ΡΡ‚Π²ΠΈΠΉ ΠΌΠ΅Π΄Π»Π΅Π½Π½ΠΎ Π·Π°Π³Ρ€ΡƒΠΆΠ°Π»Π° Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Ρ‹ поиска. ΠžΡΠ½ΠΎΠ²Π½Ρ‹ΠΌΠΈ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ°ΠΌΠΈ Π±Ρ‹Π»ΠΈ:

  • 4-сСкундная Π·Π°Π΄Π΅Ρ€ΠΆΠΊΠ° ΠΏΡ€ΠΈ Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠ΅ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ΠΎΠ².
  • Π›Π°Π³ΠΈ ΠΏΡ€ΠΈ Π²Π²ΠΎΠ΄Π΅ тСкста Π² поискС ΠΈΠ·-Π·Π° постоянных пСрСрисовок.

ΠžΠΏΠΈΡΠ°Π½Π½Ρ‹Π΅ Π²Ρ‹ΡˆΠ΅ способы диагностики ΠΏΠΎΠΌΠΎΠ³Π»ΠΈ Π²Ρ‹ΡΡΠ½ΠΈΡ‚ΡŒ ΠΏΡ€ΠΈΡ‡ΠΈΠ½Ρ‹:

  • ΠšΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ SearchResults Π½Π΅ Π±Ρ‹Π» ΠΌΠ΅ΠΌΠΎΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½, поэтому пСрСрисовывался ΠΏΡ€ΠΈ ΠΊΠ°ΠΆΠ΄ΠΎΠΌ Π½Π°ΠΆΠ°Ρ‚ΠΈΠΈ клавиши.
  • API-запросы ΠΎΡ‚ΠΏΡ€Π°Π²Π»ΡΠ»ΠΈΡΡŒ Π½Π° ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ символ, пСрСгруТая сСрвСр.

РСшСниС:

1. ДСбаунс (ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ Π»ΠΈΡˆΠ½ΠΈΡ… API-запросов). Π”ΠΎΠ±Π°Π²ΠΈΠ»ΠΈ Π·Π°Π΄Π΅Ρ€ΠΆΠΊΡƒ 500 мс, Ρ‡Ρ‚ΠΎΠ±Ρ‹ API-запрос отправлялся Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΊΠΎΠ³Π΄Π° ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ пСрСстаСт ΠΏΠ΅Ρ‡Π°Ρ‚Π°Ρ‚ΡŒ:

const SearchInput = () => {
  const [query, setQuery] = useState('');
  const debouncedQuery = useDebounce(query, 500); // Π–Π΄Π΅ΠΌ 500 мс ΠΏΠ΅Ρ€Π΅Π΄ запросом

  useEffect(() => {
    fetchResults(debouncedQuery); // Запрос Ρ‚ΠΎΠ»ΡŒΠΊΠΎ послС ΠΏΠ°ΡƒΠ·Ρ‹ Π² Π²Π²ΠΎΠ΄Π΅
  }, [debouncedQuery]);
};

Π Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚:

  • Π˜ΡΡ‡Π΅Π·Π»ΠΈ лишниС запросы ΠΏΡ€ΠΈ Π½Π°Π±ΠΎΡ€Π΅ тСкста, снизилась Π½Π°Π³Ρ€ΡƒΠ·ΠΊΠ° Π½Π° API.
  • Π£ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ появилось ΠΎΡ‰ΡƒΡ‰Π΅Π½ΠΈΠ΅ ΠΏΠ»Π°Π²Π½ΠΎΠ³ΠΎ Π²Π²ΠΎΠ΄Π° Π±Π΅Π· Π»Π°Π³ΠΎΠ².

2. ΠœΠ΅ΠΌΠΎΠΈΠ·Π°Ρ†ΠΈΡ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ΠΎΠ² (useMemo). ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Ρ‹ поиска ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Π»ΠΈΡΡŒ Π·Π°Π½ΠΎΠ²ΠΎ ΠΏΡ€ΠΈ ΠΊΠ°ΠΆΠ΄ΠΎΠΌ Ρ€Π΅Π½Π΄Π΅Ρ€Π΅, Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Π±Ρ‹Π»ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ useMemo для ΠΊΠ΅ΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΡ Π΄Π°Π½Π½Ρ‹Ρ…:

const results = useMemo(() => processRawData(rawData), [rawData]);

Π Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚:

  • Если Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ rawData Π½Π΅ измСнилось, ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° Π½Π΅ выполняСтся Π·Π°Π½ΠΎΠ²ΠΎ.
  • Бнизилась Π½Π°Π³Ρ€ΡƒΠ·ΠΊΠ° Π½Π° CPU.
  • Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° пСрСстала Ρ‚ΠΎΡ€ΠΌΠΎΠ·ΠΈΡ‚ΡŒ.

ΠžΠ±Ρ‰ΠΈΠΉ ΠΈΡ‚ΠΎΠ³ ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΠΈ – врСмя Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ снизилось с 4 с Π΄ΠΎ 1,2 с, Π»Π°Π³ΠΈ ΠΏΡ€ΠΈ Π²Π²ΠΎΠ΄Π΅ тСкста исчСзли, ΠΏΡ€ΠΎΠΊΡ€ΡƒΡ‚ΠΊΠ° стала ΠΏΠ»Π°Π²Π½ΠΎΠΉ.

React.js – мощная Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° для создания ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΈΡ… интСрфСйсов, Π½ΠΎ ΠΌΠ½ΠΎΠ³ΠΈΠ΅ Π½Π°Ρ‡ΠΈΠ½Π°ΡŽΡ‰ΠΈΠ΅ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΈ Π½Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ Π΅Π³ΠΎ Π½Π° ΠΏΠΎΠ»Π½ΡƒΡŽ силу. Π’ этой ΡΡ‚Π°Ρ‚ΡŒΠ΅ Ρ€Π°Π·Π±Π΅Ρ€Π΅ΠΌ 5 ΠΏΠΎΠ»Π΅Π·Π½Ρ‹Ρ… Ρ…Π°ΠΊΠΎΠ², ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΏΠΎΠΌΠΎΠ³ΡƒΡ‚ Π²Π°ΠΌ ΠΏΠΈΡΠ°Ρ‚ΡŒ Π±ΠΎΠ»Π΅Π΅ чистый, ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ ΠΈ ΡƒΠ΄ΠΎΠ±Π½Ρ‹ΠΉ Π² ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ΅ ΠΊΠΎΠ΄.

ЧастыС ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹ с ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒΡŽ React-ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ

ΠŸΠΎΡ‡Π΅ΠΌΡƒ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠ°Π΅Ρ‚ Ρ‚ΠΎΡ€ΠΌΠΎΠ·ΠΈΡ‚ΡŒ Π΄Π°ΠΆΠ΅ с ΡƒΡ‡Π΅Ρ‚ΠΎΠΌ React.memo?

React.memo Π½Π΅ избавляСт ΠΎΡ‚ всСх ΠΏΠΎΠ΄Π²ΠΎΠ΄Π½Ρ‹Ρ… ΠΊΠ°ΠΌΠ½Π΅ΠΉ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΌΠΎΠ³ΡƒΡ‚ Π²Ρ‹Π·Π²Π°Ρ‚ΡŒ лишниС Ρ€Π΅Π½Π΄Π΅Ρ€Ρ‹. ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡŒΡ‚Π΅ эти ΠΌΠΎΠΌΠ΅Π½Ρ‚Ρ‹:

1. ΠŸΠ΅Ρ€Π΅Π΄Π°Ρ‡Π° Π½ΠΎΠ²Ρ‹Ρ… ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ²/массивов Π² пропсы (ΠΎΠ½ΠΈ ΡΠΎΠ·Π΄Π°ΡŽΡ‚ΡΡ Π·Π°Π½ΠΎΠ²ΠΎ Π½Π° ΠΊΠ°ΠΆΠ΄ΠΎΠΌ Ρ€Π΅Π½Π΄Π΅Ρ€Π΅):

<MyComponent style={{ color: 'red' }} /> // Новый ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ ΠΏΡ€ΠΈ ΠΊΠ°ΠΆΠ΄ΠΎΠΌ Ρ€Π΅Π½Π΄Π΅Ρ€Π΅!

Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ useMemo ΠΈΠ»ΠΈ выноситС ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ Π·Π° ΠΏΡ€Π΅Π΄Π΅Π»Ρ‹ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π°.

2. ΠŸΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»ΠΈ контСкста (useContext) ΠΌΠΎΠ³ΡƒΡ‚ ΠΎΠ±Π½ΠΎΠ²Π»ΡΡ‚ΡŒΡΡ ΠΏΡ€ΠΈ ΠΊΠ°ΠΆΠ΄ΠΎΠΌ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΈ. НС Π·Π°Π±ΡƒΠ΄ΡŒΡ‚Π΅ Ρ€Π°Π·Π΄Π΅Π»ΠΈΡ‚ΡŒ контСксты (UserContext, ThemeContext ΠΈ Ρ‚. Π΄.), Ρ‡Ρ‚ΠΎΠ±Ρ‹ обновлялась Ρ‚ΠΎΠ»ΡŒΠΊΠΎ нуТная Ρ‡Π°ΡΡ‚ΡŒ UI.

Π‘Ρ‚ΠΎΠΈΡ‚ Π»ΠΈ ΡƒΡΠ»ΠΎΠΆΠ½ΡΡ‚ΡŒ ΠΊΠΎΠ΄ Ρ€Π°Π΄ΠΈ ΠΎΡ‚Π»ΠΎΠΆΠ΅Π½Π½ΠΎΠΉ Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ?

  • Π”Π°, Ссли ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ Π½Π΅ Π²ΠΈΠ΄Π΅Π½ сразу (располагаСтся Π½ΠΈΠΆΠ΅ ΠΏΠ΅Ρ€Π²ΠΎΠ³ΠΎ экрана). Π­Ρ‚ΠΎ ΡƒΠΌΠ΅Π½ΡŒΡˆΠ°Π΅Ρ‚ Ρ€Π°Π·ΠΌΠ΅Ρ€ ΠΏΠ΅Ρ€Π²ΠΎΠ³ΠΎ Π·Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌΠΎΠ³ΠΎ Π±Π°Π½Π΄Π»Π°.
  • НСт, Ссли ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ Π²Π°ΠΆΠ΅Π½ для ΠΏΠ΅Ρ€Π²ΠΎΠ³ΠΎ Ρ€Π΅Π½Π΄Π΅Ρ€Π° (шапка, Π³Π»Π°Π²Π½ΠΎΠ΅ мСню). Π’ этом случаС отлоТСнная Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠ° Π·Π°ΠΌΠ΅Π΄Π»ΠΈΡ‚ ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ страницы.

Как ΡƒΠ±Π΅Π΄ΠΈΡ‚ΡŒ ΠΊΠΎΠΌΠ°Π½Π΄Ρƒ, Ρ‡Ρ‚ΠΎ ΠΏΠΎΡ€Π° ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΡΠΊΠΎΡ€ΠΎΡΡ‚ΡŒ?

ΠŸΡ€ΠΎΠ΄Π΅ΠΌΠΎΠ½ΡΡ‚Ρ€ΠΈΡ€ΡƒΠΉΡ‚Π΅ ΠΈΠΌ Lighthouse-ΠΎΡ‚Ρ‡Π΅Ρ‚Ρ‹ ΠΏΠ΅Ρ€Π΅Π΄ ΠΈ послС ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΠΈ. ИсслСдованиС Deloitte ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ ускорСниС сайта всСго Π½Π° 0,1 с ΠΏΠΎΠ²Ρ‹ΡˆΠ°Π΅Ρ‚ конвСрсии Π½Π° 8,4-10,1%.

ПодвСдСм ΠΈΡ‚ΠΎΠ³ΠΈ

ΠžΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΡ React-ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ – это Π½Π΅ Ρ€Π°Π·ΠΎΠ²ΠΎΠ΅ дСйствиС, Π° процСсс. Π“Π»Π°Π²Π½ΠΎΠ΅ – Π½Π΅ ΠΏΡ‹Ρ‚Π°Ρ‚ΡŒΡΡ ΡƒΠ»ΡƒΡ‡ΡˆΠΈΡ‚ΡŒ ΠΊΠΎΠ΄ Π²ΡΠ»Π΅ΠΏΡƒΡŽ:

  • Π‘Π½Π°Ρ‡Π°Π»Π° ΠΏΡ€ΠΎΡ„ΠΈΠ»ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅, ΠΏΠΎΡ‚ΠΎΠΌ оптимизация. НС Π³Π°Π΄Π°ΠΉΡ‚Π΅, Π³Π΄Π΅ находятся ΡƒΠ·ΠΊΠΈΠ΅ мСста Π² вашСм ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΈ. Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½Ρ‹Π΅ Π΄Π°Π½Π½Ρ‹Π΅ для выявлСния Ρ€Π΅Π°Π»ΡŒΠ½Ρ‹Ρ… ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ.
  • Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ React DevTools. Π­Ρ‚ΠΎ ΠΎΡ‚Π»ΠΈΡ‡Π½Ρ‹ΠΉ инструмСнт для поиска фактичСских ΡƒΠ·ΠΊΠΈΡ… мСст Π² вашСм ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΈ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ даст Π²Π°ΠΌ Ρ‚ΠΎΡ‡Π½ΡƒΡŽ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ ΠΎ Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ Π½ΡƒΠΆΠ½ΠΎ ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ.
  • НС ΠΎΠ±ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°ΠΉΡ‚Π΅ всС Π² useMemo Π½Π° всякий случай. Π­Ρ‚ΠΎ ΠΌΠΎΠΆΠ΅Ρ‚ Π²Ρ‹Π·Π²Π°Ρ‚ΡŒ большС ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌ, Ρ‡Π΅ΠΌ Ρ€Π΅ΡˆΠΈΡ‚.
  • ΠŸΡ€ΠΈΠΌΠΈΡ‚Π΅ Π½Π΅ΡΠΎΠ²Π΅Ρ€ΡˆΠ΅Π½ΡΡ‚Π²ΠΎ. Π’ΠΎΡ‡Π΅Ρ‡Π½ΠΎ ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠ΅ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ Π½Π° 90% быстрСС с нСбольшими компромиссами, Π»ΡƒΡ‡ΡˆΠ΅ гипотСтичСского идСального прилоТСния, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ Π½ΠΈΠΊΠΎΠ³Π΄Π° Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹ΠΏΡƒΡ‰Π΅Π½ΠΎ.

Π›Π£Π§Π¨Π˜Π• БВАВЬИ ПО Π’Π•ΠœΠ•