React Performance Patterns
React sangat cepat secara default, tapi aplikasi besar bisa mengalami masalah re-render berlebihan. Memahami kapan dan bagaimana mengoptimasi adalah kunci.
Kenapa React Re-render?
React re-render komponen ketika:
- State berubah —
useState,useReducer - Props berubah — parent kirim props baru
- Context berubah — value context provider berubah
- Parent re-render — secara default, semua child ikut re-render
React.memo — Skip Re-render
// Tanpa memo: re-render setiap kali parent re-render
function UserCard({ user }) {
return <div>{user.name}</div>;
}
// Dengan memo: hanya re-render jika props berubah
const UserCard = React.memo(function UserCard({ user }) {
return <div>{user.name}</div>;
});
Kapan pakai React.memo?
- Komponen yang render sering (list items, table rows)
- Props jarang berubah
- Komponen yang expensive (banyak komputasi / DOM)
useMemo — Memoize Nilai
// Tanpa useMemo: dihitung ulang setiap render
const sortedData = data.sort((a, b) => a.price - b.price);
// Dengan useMemo: hanya dihitung ulang jika data berubah
const sortedData = useMemo(
() => data.sort((a, b) => a.price - b.price),
[data]
);
useCallback — Memoize Fungsi
// Tanpa useCallback: fungsi baru dibuat setiap render
// Ini menyebabkan child yang pakai React.memo tetap re-render!
const handleClick = () => updateItem(id);
// Dengan useCallback: fungsi sama selama id tidak berubah
const handleClick = useCallback(() => updateItem(id), [id]);
Profiler — Ukur Sebelum Optimasi
import { Profiler } from "react";
function onRenderCallback(id, phase, actualDuration) {
console.log(`${id} (${phase}): ${actualDuration.toFixed(2)}ms`);
}
<Profiler id="UserList" onRender={onRenderCallback}>
<UserList data={data} />
</Profiler>
Aturan emas: Jangan optimasi prematur. Ukur dulu, optimasi kemudian.