Cara Memoize Fungsi dan Nilai dalam JavaScript dan Bereaksi

Memoization adalah teknik optimasi, mirip dengan caching. Ini bekerja dengan menyimpan hasil panggilan fungsi sebelumnya dan menggunakan hasil tersebut saat fungsi berjalan berikutnya. Ini sangat berguna dalam aplikasi komputasi berat yang mengulang panggilan fungsi pada parameter yang sama.

Anda dapat menggunakan memoisasi dalam JavaScript biasa dan juga di React, dalam beberapa cara berbeda.


Memoisasi dalam JavaScript

Untuk memoize suatu fungsi dalam JavaScript, Anda perlu menyimpan hasil fungsi tersebut dalam cache. Cache dapat berupa objek dengan argumen sebagai kunci dan hasil sebagai nilai.

Saat Anda memanggil fungsi ini, pertama-tama ia akan memeriksa apakah hasilnya ada di cache sebelum dijalankan. Jika ya, ia mengembalikan hasil yang di-cache. Jika tidak, itu akan dieksekusi.

Pertimbangkan fungsi ini:

function square(num) {
return num * num
}

Fungsi menerima argumen dan mengembalikan kuadratnya.

Untuk menjalankan fungsi tersebut, panggil dengan nomor seperti ini:

square(5) 

Dengan 5 sebagai argumen, square() akan berjalan cukup cepat. Namun, jika Anda menghitung kuadrat dari 70.000, akan ada penundaan yang nyata. Tidak banyak tapi penundaan tetap. Sekarang, jika Anda memanggil fungsi beberapa kali dan melewati 70.000, Anda akan mengalami penundaan di setiap panggilan.

Anda dapat menghilangkan penundaan ini menggunakan memoisasi.

const memoizedSquare = () => {
let cache = {};
return (num) => {
if (num in cache) {
console.log('Reusing cached value');
return cache[num];
} else {
console.log('Calculating result');
let result = num * num;

// cache the new result value for next time
cache[num] = result;
return result;
}
}
}

Dalam contoh ini, fungsi memeriksa apakah hasil telah dihitung sebelumnya, dengan memeriksa apakah ada di objek cache. Jika memilikinya mengembalikan nilai yang sudah dihitung.

See also  Cara Mematikan Layar MacBook Anda: 3 Metode

Ketika fungsi menerima nomor baru, ia menghitung nilai baru dan menyimpan hasilnya dalam cache sebelum kembali.

Sekali lagi contoh ini cukup sederhana, tetapi menjelaskan bagaimana memoisasi akan bekerja untuk meningkatkan kinerja suatu program.

Anda hanya boleh memoize fungsi murni. Fungsi-fungsi ini mengembalikan hasil yang sama ketika Anda memasukkan argumen yang sama. Jika Anda menggunakan memoisasi pada fungsi yang tidak murni, Anda tidak akan meningkatkan kinerja tetapi meningkatkan overhead Anda. Itu karena Anda memilih kecepatan daripada memori setiap kali Anda memoize suatu fungsi.

Memoisasi di React

Jika Anda ingin mengoptimalkan komponen React, React menyediakan memoisasi melalui hook useMemo(), React.memo, dan useCallBack().

Menggunakan useMemo()

useMemo() adalah kait React yang menerima fungsi dan larik dependensi.

const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);

Itu memoizes nilai yang dikembalikan dari fungsi itu. Nilai dalam larik dependensi menentukan kapan fungsi dijalankan. Hanya ketika mereka berubah, fungsi tersebut dieksekusi lagi.

Misalnya, komponen Aplikasi berikut memiliki nilai memo yang disebut hasil.

import { useMemo } from "react"
function App(value) {
const square = (value) => {
return value * value
}
const result = useMemo(
() => square(value),
[ value ]
);
return (
<div>{result(5)}</div>
)
}

Komponen Aplikasi memanggil square() pada setiap render. Performa akan menurun jika komponen Aplikasi dirender berkali-kali karena perubahan props React atau pembaruan status, terutama jika fungsi square() mahal.

Namun, karena useMemo() men-cache nilai yang dikembalikan, fungsi kuadrat tidak dijalankan di setiap render ulang kecuali argumen dalam larik dependensi berubah.

Menggunakan React.memo()

React.memo() adalah komponen tingkat tinggi yang menerima komponen React dan fungsi sebagai argumen. Fungsi menentukan kapan komponen harus diperbarui.

See also  Cara Kerja Scoping di JavaScript

Fungsi ini opsional dan jika tidak disediakan, React.memo membuat perbandingan salinan sederhana dari prop komponen saat ini dengan prop sebelumnya. Jika alat peraga berbeda, itu memicu pembaruan. Jika propsnya sama, ia akan melewatkan rendering ulang dan menggunakan kembali nilai memo.

Fungsi opsional menerima props sebelumnya dan props berikutnya sebagai argumen. Anda kemudian dapat secara eksplisit membandingkan alat peraga ini untuk memutuskan apakah akan memperbarui komponen atau tidak.

React.memo(Component, [areEqual(prevProps, nextProps)])

Mari kita lihat contoh tanpa argumen fungsi opsional terlebih dahulu. Di bawah ini adalah komponen yang disebut Komentar yang menerima props nama dan email.

function Comments ({name, comment, likes}) {
return (
<div>
<p>{name}</p>
<p>{comment}</p>
<p>{likes}</p>
</div>
)
}

Komponen komentar memo akan membuat React.memo membungkusnya seperti ini:

const MemoizedComment = React.memo(Comment)

Anda dapat memanggil lalu memanggilnya seperti komponen React lainnya.

<MemoizedComment name="Mary" comment="Memoization is great" likes=1/>

Jika Anda ingin melakukan perbandingan props sendiri, berikan fungsi berikut ke React.memo sebagai argumen kedua.

import React from "react"
function checkCommentProps(prevProps, nextProps) {
return prevProps.name === nextProps.name
&& prevProps.comment === nextProps.comment
&& prevProps.likes === nextProps.likes
}

const MemoizedComment = React.memo(Comments, checkCommentProps)

Jika checkProfileProps mengembalikan nilai true, komponen tidak diperbarui. Jika tidak, itu dirender ulang.

Fungsi kustom berguna saat Anda ingin menyesuaikan render ulang. Misalnya, Anda dapat menggunakannya untuk memperbarui komponen Komentar hanya ketika jumlah suka berubah.

Tidak seperti hook useMemo() yang hanya mencatat nilai yang dikembalikan dari suatu fungsi, React.memo memoize seluruh fungsi.

Gunakan React.memo hanya untuk komponen murni. Juga, untuk mengurangi biaya perbandingan, hanya memoize komponen yang alat peraganya sering berubah.

See also  5 Cara Penting untuk Mengurutkan DataFrames dengan Python

Menggunakan useCallBack()

Anda dapat menggunakan kait useCallBack() untuk memoize komponen fungsi.

const memoizedCallback = useCallback(
() => {
doSomething(a, b);
},
[a, b],
);

Fungsi akan diperbarui hanya ketika nilai dalam larik dependensi berubah. Hook berfungsi seperti callback useMemo() , tetapi memoize komponen fungsi di antara render alih-alih memoizing nilai.

Pertimbangkan contoh berikut dari fungsi memo yang memanggil API.

import { useCallback, useEffect } from "react";
const Component = () => {
const getData = useCallback(() => {
console.log('call an API');
}, []);
useEffect(() => {
getData();
}, [getData]);
};

Fungsi getData() yang dipanggil di useEffect akan dipanggil lagi hanya ketika nilai getData berubah.

Haruskah Anda Menghafal?

Dalam tutorial ini, Anda mempelajari apa itu memoisasi, manfaatnya, dan bagaimana menerapkannya dalam JavaScript dan React. Namun, Anda harus tahu bahwa React sudah cepat. Dalam kebanyakan kasus, memoisasi komponen atau nilai menambah biaya perbandingan dan tidak meningkatkan kinerja. Karena itu, hanya memoize komponen yang mahal.

React 18 juga memperkenalkan kait baru seperti useId, useTransition, dan useInsertionEffect. Anda dapat menggunakan ini untuk meningkatkan kinerja dan pengalaman pengguna aplikasi React.