Những điểm cần lưu ý để cải thiện performance của react app - phần 1
Bài đăng này đã không được cập nhật trong 5 năm
Bản thân React đã sử dụng những kỹ thuật để tối ưu hoá quá trình render UI, nhưng tuỳ vào độ phức tạp và business của app mà bản thân React không thể đáp ứng đủ tối ưu hoá quá trình render; vì vậy chúng ta cần implement những kỹ thuật để cải thiện performance của app.
Sử dụng shouldComponentUpdate
Thông thường các child components luôn luôn re-render lại theo parent component cho dù những props truyền vào cho các child components này không thay đổi.
Trong thực tế chúng ta chỉ cần render child components chỉ khi props truyền vào thay đổi, để làm được điều này chúng ta cần implement hàm shouldComponentUpdate như sau:
shouldComponentUpdate(nextProps, nextState) {
    if (nextProps.data === this.props.data) {
        return false; // skip re-render component
    }
  return true; // re-render component (default)
}
Trong hầu hết tất cả các trường hợp, thay vì ta implement hàm shouldComponentUpdate manual, thì có thể kế thừa một class component từ PureComponent thay vì Component.
PureComponent tương tự như shouldComponentUpdate với shallow comparison của props, state
Tương tự với PureComponent trong class component thì ta có thể sử dụng React.memo trong functional component như sau:
function MyComponent(props) {
  /* render using props */
}
export default React.memo(MyComponent);
Sử dụng useMemo, useCallback hooks trong functional component
Nếu app có những data cần tính toán phức tạp thì ta cần cached (memorized) những data này để khỏi phải tính toán lại nếu input không thay đổi.
useMemo
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
useMemo chỉ thực hiện computeExpensiveValue nếu a hoặc b thay đổi.
Chúng ta cũng có thể apply useMemo để cached một react component như sau:
const memoizedGreeting = useMemo(() => <div>Hello {name}!</div>, [name]);
useCallback
useMemo sử dụng để cached value, còn useCallback dùng để cached một callback function
Như vậy ta có thể sử dụng useCallback để cached một callback funtion không thay đổi reference trong mỗi lần render
const memoizedCallback = useCallback(
  () => {
    doSomething(a, b);
  },
  [a, b],
);
Virtualize Long Lists
Đây là kỹ thuật tối ưu performance nếu render một list data dài và phức tạp. Kỹ thuật này chỉ render một nhóm các item trong list ra trên UI chứ không render toàn bộ list data
Có nhiều libs support kỹ thuật này, mà điển hình là react-window và react-virtualized , các libs này cung cấp các components cho việc hiển thị list, grid, table.
Sử dụng Production Build
Khi release một react app chúng ta cần build ở mode production, việc này đảm bảo version react sẽ được loại bỏ các warning không cần thiết, các đoạn code debug, component, tools support khi dev và giảm build size,...
Sử dụng build file:
<script src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>
webpack:
const TerserPlugin = require('terser-webpack-plugin');
module.exports = {
  mode: 'production', // important
  optimization: {
    minimizer: [new TerserPlugin({ /* additional options here */ })],
  },
};
Kết luận
Trên đây là một số điểm cần lưu ý để cải thiện performance của react app, một số kỹ thuật nữa sẽ có trong phần tiếp theo, các bạn đón đọc nhé, xin cám ơn!
All rights reserved
 
  
 