Blogs
Tối ưu hiệu suất trong React với memo và useMemo

Tối ưu hiệu suất trong React với memo và useMemo

Cách sử dụng memo và useMemo để tránh render không cần thiết

Giới thiệu

Khi phát triển ứng dụng React, hiệu suất là một yếu tố quan trọng. Nếu không kiểm soát tốt quá trình render, ứng dụng có thể trở nên chậm chạp, đặc biệt là với các component phức tạp.

Hai kỹ thuật phổ biến để tối ưu hiệu suất render trong React là React.memouseMemo. Chúng giúp tránh việc render lại không cần thiết, từ đó cải thiện hiệu suất ứng dụng.


1. React.memo – Ghi nhớ component để tránh render lại

Mặc định, một component con sẽ bị render lại khi component cha render, dù props không thay đổi. Điều này có thể gây lãng phí tài nguyên.

React.memo giúp React "ghi nhớ" component và chỉ re-render khi props thực sự thay đổi.

Cách sử dụng React.memo

import React from "react"; const Button = React.memo(({ onClick, children }: { onClick: () => void; children: React.ReactNode }) => { console.log("Button render"); return <button onClick={onClick}>{children}</button>; }); export default function App() { const [count, setCount] = React.useState(0); return ( <div> <h1>Count: {count}</h1> <Button onClick={() => setCount(count + 1)}>Tăng</Button> </div> ); }

Giải thích:

  • Khi App re-render, component Button cũng sẽ bị re-render theo mặc định, ngay cả khi props không thay đổi.
  • React.memo giúp ngăn chặn điều này bằng cách ghi nhớ kết quả render trước đóchỉ re-render nếu props thay đổi.
  • Trong ví dụ trên, nếu onClick không thay đổi giữa các lần render, Button sẽ không bị render lại.
  • Điều này giúp giảm số lần render không cần thiết, đặc biệt hữu ích khi component con phức tạp hoặc chứa nhiều logic.

Khi nào nên dùng React.memo?

  • Khi component con có render phức tạp.
  • Khi component con nhận props không đổi từ component cha.
  • Khi cần tối ưu hiệu suất trong danh sách lớn hoặc UI động.

Không nên dùng React.memo cho mọi component Nếu component render nhanh, memo có thể khiến React phải tốn công kiểm tra props, làm giảm hiệu suất.


2. useMemo – Ghi nhớ giá trị để tránh tính toán lại

useMemo giúp lưu lại kết quả tính toán và chỉ cập nhật khi dependency thay đổi. Điều này hữu ích khi tính toán phức tạp hoặc xử lý dữ liệu lớn.

Cách sử dụng useMemo

import React, { useState, useMemo } from "react"; function App() { const [count, setCount] = useState(0); const [number, setNumber] = useState(10); const expensiveCalculation = (num: number) => { console.log("Tính toán..."); return num * 2; }; // Chỉ tính toán lại khi number thay đổi const memoizedValue = useMemo(() => expensiveCalculation(number), [number]); return ( <div> <h1>Kết quả: {memoizedValue}</h1> <button onClick={() => setNumber(number + 1)}>Tăng Number</button> <button onClick={() => setCount(count + 1)}>Tăng Count</button> <p>Count: {count}</p> </div> ); } export default App;

Giải thích:

  • useMemo lưu kết quả của expensiveCalculation(number), chỉ tính toán lại khi number thay đổi.
  • Nếu chỉ count thay đổi, React sử dụng lại giá trị đã tính trước đó, giúp tăng hiệu suất.

Khi nào nên dùng useMemo?

  • Khi tính toán phức tạp (ví dụ: lọc danh sách, tính toán toán học).
  • Khi dữ liệu không cần thay đổi thường xuyên.
  • Khi render lại component có thể gây chậm UI.

Không nên dùng useMemo với các giá trị tính toán đơn giản, vì React vẫn phải kiểm tra dependency array.


3. memo vs. useMemo – Sử dụng khi nào?

Trường hợp sử dụngDùng React.memoDùng useMemo
Tránh re-render component con
Tối ưu giá trị tính toán nặng
Component nhận props không đổi
Tránh tính toán lại trong mỗi render

Kết luận

  • Dùng React.memo khi muốn tránh re-render component không cần thiết.
  • Dùng useMemo khi muốn tối ưu hiệu suất của các tính toán phức tạp.
  • Đừng lạm dụng! Chỉ dùng khi thực sự có vấn đề về hiệu suất, tránh làm code phức tạp hơn.

Optimizing Performance in React with memo and useMemo

How to use memo and useMemo to prevent unnecessary renders

Introduction

When developing React applications, performance is a crucial factor. If rendering is not well-managed, the app can become sluggish, especially with complex components.

Two popular techniques for optimizing rendering performance in React are React.memo and useMemo. They help avoid unnecessary re-renders, improving the overall performance of your application.


1. React.memo – Memoizing a component to prevent unnecessary renders

By default, a child component re-renders whenever its parent renders, even if the props haven’t changed. This can waste resources.

React.memo allows React to "remember" a component and only re-render it when its props actually change.

How to use React.memo

import React from "react"; const Button = React.memo(({ onClick, children }: { onClick: () => void; children: React.ReactNode }) => { console.log("Button render"); return <button onClick={onClick}>{children}</button>; }); export default function App() { const [count, setCount] = React.useState(0); return ( <div> <h1>Count: {count}</h1> <Button onClick={() => setCount(count + 1)}>Increase</Button> </div> ); }

Explanation:

  • When App re-renders, the Button component will also re-render by default, even if the props haven't changed.
  • React.memo helps prevent this by caching the previous render result and only re-rendering if the props change.
  • In the example above, if onClick doesn’t change between renders, the Button won’t re-render.
  • This helps reduce unnecessary renders, especially useful for complex or logic-heavy child components.

When should you use React.memo?

  • When the child component has expensive rendering logic.
  • When the child receives props that don’t change between renders.
  • When optimizing performance for large lists or dynamic UIs.

You shouldn't use React.memo for every component. If a component renders quickly, memoization can add unnecessary overhead due to props comparison, which might actually reduce performance.


2. useMemo – Memoizing a value to avoid re-computation

useMemo helps cache computed values and only recomputes them when dependencies change. This is useful for expensive calculations or large data processing.

How to use useMemo

import React, { useState, useMemo } from "react"; function App() { const [count, setCount] = useState(0); const [number, setNumber] = useState(10); const expensiveCalculation = (num: number) => { console.log("Calculating..."); return num * 2; }; // Only re-computes when 'number' changes const memoizedValue = useMemo(() => expensiveCalculation(number), [number]); return ( <div> <h1>Result: {memoizedValue}</h1> <button onClick={() => setNumber(number + 1)}>Increase Number</button> <button onClick={() => setCount(count + 1)}>Increase Count</button> <p>Count: {count}</p> </div> ); } export default App;

Explanation:

  • useMemo stores the result of expensiveCalculation(number) and only recomputes it when number changes.
  • If only count changes, React uses the previously computed value, helping improve performance.

When should you use useMemo?

  • When performing expensive calculations (e.g., filtering a list, mathematical operations).
  • When data doesn’t change frequently.
  • When component re-renders could slow down the UI.

You shouldn’t use useMemo for simple calculations, as React still needs to check the dependency array.


3. memo vs. useMemo – When to use which?

Use CaseUse React.memoUse useMemo
Prevent re-render of child component
Optimize heavy computations
Component receives unchanged props
Avoid re-computing values on render

Conclusion

  • Use React.memo to prevent unnecessary re-renders of components.
  • Use useMemo to optimize performance for expensive computations.
  • Don’t overuse! Only apply them when facing real performance issues to avoid adding unnecessary complexity to your code.

Tags

Buy Me A Coffee
    ReactJSPerformance