Meningkatkan performance menggunakan useMemo dan useCallback
Ketika mengembangkan web dengan fitur yang kompleks, akan ada banyak perubahan state pada setiap komponen. Dalam penggunaan React, perubahan satu state bisa menyebabkan komponen lain ikut di-render ulang. Bayangkan jika ada satu komponen yang memiliki beban kerja berat, tetapi kita hanya ingin mengubah state pada komponen yang lebih ringan. Hal ini dapat menyebabkan komponen ringan tersebut juga terasa lambat. Untuk menghadapi situasi seperti ini, kita bisa memanfaatkan useMemo dan useCallback sesuai dengan kebutuhan.
useMemo vs useCallback
Baik, perbedaan mendasar antara useCallback
dan useMemo
dalam React adalah sebagai berikut
useCallback
: Digunakan untuk mengoptimalkan performa dengan mengingat kembali (memorize) versi dari sebuah fungsi callback yang sama, sehingga fungsi tersebut tidak di-create ulang setiap kali komponen dirender ulang, kecuali jika dependensi berubah.
useMemo
: Digunakan untuk mengoptimalkan performa dengan mengingat kembali (memorize) hasil dari ekspresi pemrograman (baik itu nilai dari sebuah komputasi atau sebuah objek) sehingga nilai tersebut tidak dihitung ulang setiap kali komponen dirender ulang, kecuali jika dependensi berubah.
yup, mungkin aga sedikit membingungkan, akan tetapi pada intinya useCallback mengingat kembali fungsi sedangkan useMemo mengingat kembali value dari fungsi apabila tidak ada perubahan terhadap depedensi
Contoh Penggunaan useMemo
import React, { useState, useMemo } from 'react';
function ExpensiveComputationComponent() {
const [count, setCount] = useState(0);
const [inputValue, setInputValue] = useState('');
// Fungsi ini melakukan perhitungan yang berat
const expensiveComputation = (num) => {
console.log('Computing...');
for (let i = 0; i < 1000000000; i++) {
console.log(i)
} // Simulasi perhitungan berat
return num * 2;
};
// Menggunakan useMemo untuk menghindari perhitungan ulang yang tidak perlu
const computedValue = useMemo(() => {
return expensiveComputation(count);
}, [count]);
return (
<div>
<h1>Count: {count}</h1>
<h2>Computed Value: {computedValue}</h2>
<button onClick={() => setCount(count + 1)}>Increment Count</button>
<br />
<input
type="text"
value={inputValue}
onChange={(e) => setInputValue(e.target.value)}
placeholder="Type something"
/>
<p>Input Value: {inputValue}</p>
</div>
);
}
export default ExpensiveComputationComponent;
Dalam contoh di atas:
- expensiveComputation adalah fungsi yang melakukan perhitungan berat.
- useMemo digunakan untuk mengoptimalkan perhitungan computedValue sehingga hanya dihitung ulang ketika count berubah.
- Tanpa useMemo, expensiveComputation akan dipanggil setiap kali komponen dirender, termasuk saat inputValue berubah. Dengan useMemo, perhitungan hanya dilakukan saat count berubah, meningkatkan kinerja komponen.
Contoh Penggunaan useCallback
Penggunaan useCallback akan lebih powerfull jika dikombinasikan dengan React.memo
import React, { useState, useCallback, memo } from 'react';
const Button = memo(({ onClick, children }) => {
console.log(`Rendering button: ${children}`);
return <button onClick={onClick}>{children}</button>;
});
function ParentComponent() {
const [count, setCount] = useState(0);
const [otherState, setOtherState] = useState(false);
const increment = useCallback(() => {
setCount(prevCount => prevCount + 1);
}, []);
const toggleOtherState = () => {
setOtherState(prevState => !prevState);
};
return (
<div>
<h1>Count: {count}</h1>
<Button onClick={increment}>Increment</Button>
<button onClick={toggleOtherState}>Toggle Other State</button>
<p>Other state: {otherState.toString()}</p>
</div>
);
}
export default ParentComponent;
Dalam contoh ini:
- Komponen
Button
di-memoize menggunakanReact.memo
untuk mencegah render ulang yang tidak perlu. increment
di-memoize menggunakanuseCallback
sehingga fungsi yang sama akan digunakan kembali pada setiap render, kecuali jika dependensinya berubah.- Ketika
otherState
berubah,Button
tidak akan dirender ulang karenaincrement
tidak berubah.
Kesimpulan
Penggunaan useMemo dan useCallback sangat membantu dalam meningkatkan performa aplikasi dengan mengoptimalkan penggunaan sumber daya komputasi. Namun, tidak semua fungsi perlu diterapkan dengan kedua hooks tersebut. Penting untuk mempertimbangkan implementasi useMemo dan useCallback secara selektif, terutama untuk fungsi-fungsi yang memiliki biaya komputasi tinggi atau memori besar. Menggunakan kedua hooks secara berlebihan dapat menambah overhead yang tidak perlu, terutama jika fungsi tersebut jarang dipanggil atau tidak memerlukan pengoptimalan khusus.
Referensi :