Trong phát triển ứng dụng web hiện đại, hiệu suất là điều kiện tiên quyết cho sự thành công của mọi ứng dụng. Đối với các dự án xây dựng trên nền tảng React, việc tối ưu hóa hiệu suất trở nên cực kỳ quan trọng. Một trong những yếu tố chính ảnh hưởng đến hiệu suất của ứng dụng React là việc render lại các component không cần thiết.
Để hiểu rõ hơn về vấn đề này, bài viết sẽ phân tích một số sai lầm phổ biến mà các lập trình viên React thường mắc phải và cách khắc phục để gia tăng hiệu suất cho ứng dụng.
1. Tránh lạm dụng hàm inline quá mức
Việc lạm dụng hàm inline trong JSX có thể gây ra render không mong muốn. Khi React phát hiện một hàm mới được tạo ra trong mỗi lần render, nó sẽ coi đó như một prop mới.
Ví dụ sai cách:
jsx
function ButtonComponent() {
return <button onClick={() => handleClick()}>Click me</button>;
}
Trong ví dụ trên, hàm handleClick
sẽ bị tạo ra liên tục, dẫn đến việc tốn thêm tài nguyên không cần thiết. Để khắc phục, bạn có thể sử dụng useCallback
, giúp ghi nhớ hàm và ngăn chặn việc tạo lại trong mỗi lần render.
Giải pháp:
jsx
import { useCallback } from 'react';
function ButtonComponent() {
const handleClick = useCallback(() => {
// Logic xử lý khi nhấn
}, []);
return <button onClick={handleClick}>Click me</button>;
}
2. Sử dụng React.memo không đúng cách
Một sai lầm phổ biến là việc chưa triển khai hàm so sánh tùy chỉnh khi sử dụng React.memo
. Mặc dù memoization giúp giới hạn render không cần thiết khi props không thay đổi, nhưng nếu hàm so sánh không được sử dụng đúng cách, có thể dẫn đến việc hiệu suất vẫn không được cải thiện.
Cách sử dụng đúng:
jsx
const MemoizedComponent = React.memo(MyComponent, (prevProps, nextProps) => {
return prevProps.itemId === nextProps.itemId;
});
Khi làm việc với component dạng class mà không sử dụng PureComponent
, bạn có thể triển khai shouldComponentUpdate
để kiểm soát render tốt hơn.
3. Sử dụng React.PureComponent để tối ưu hóa
Khi làm việc với component dạng class, bạn nên sử dụng React.PureComponent
thay vì React.Component
. React.PureComponent
đảm bảo rằng component chỉ render lại khi props hoặc state thay đổi, giúp tiết kiệm tài nguyên.
Ví dụ so sánh:
jsx
class CardComponent extends React.PureComponent {
// Logic component
}
So với việc sử dụng React.Component
, lựa chọn PureComponent
sẽ giúp tối ưu hóa hiệu suất hơn rất nhiều.
4. Tối ưu hóa không đúng cách useSelector
Việc sử dụng useSelector
từ react-redux
cũng cần được tối ưu hóa để giảm thiểu việc re-render. Chỉ chọn phần state cần thiết là rất quan trọng để tránh render lại không cần thiết.
Ví dụ sai cách:
jsx
import { useSelector } from 'react-redux';
const DataComponent = () => {
const globalState = useSelector((state) => state);
// Logic hiển thị
};
Sửa lại như sau để tối ưu hơn:
jsx
const DataComponent = () => {
const selectedData = useSelector((state) => state.specificSlice);
// Logic hiển thị trên dữ liệu đã chọn
};
Bằng cách chỉ lấy phần cần thiết của state, bạn sẽ giảm thiểu việc render lại.
5. Triển khai shouldComponentUpdate cho component class
Cuối cùng, với các component dạng class mà không mở rộng PureComponent
, việc triển khai shouldComponentUpdate
giúp bạn kiểm soát chi tiết hơn về render.
Ví dụ:
jsx
class ListItem extends React.Component {
shouldComponentUpdate(nextProps, nextState) {
return this.props.itemId !== nextProps.itemId || this.state.value !== nextState.value;
}
}
Tùy chỉnh shouldComponentUpdate
cho phép component chỉ render lại khi nào cần thiết, thay vì bị ảnh hưởng bởi việc render của component cha.
Kết luận
Tóm lại, thông qua việc áp dụng các kỹ thuật tối ưu hóa đã được thảo luận, bạn có thể giảm thiểu đáng kể việc render không cần thiết trong ứng dụng React. Mọi thao tác tối ưu hóa sẽ góp phần làm cho ứng dụng của bạn hoạt động mượt mà và hiệu quả hơn, tốt cho trải nghiệm người dùng bằng cách cung cấp các ứng dụng nhanh hơn và phản hồi nhanh chóng. Cảm ơn các bạn đã theo dõi bài viết này!
source: viblo