Một số tips để tối ưu hóa ứng dụng React (P1)

📅May 21, 2019

Chỉ cần những sai lầm ngớ ngẩn rất đơn giản thôi cũng sẽ làm giảm hiệu suất của ứng dụng React. Muốn app chạy nhanh thì trước tiên phải thực hiện tối ưu cho các phần nhỏ.

Sử dụng Functional / Stateless Component và PureComponent

Trong React, có tất cả 3 loại Component chính: Functional Component, Class Component và Pure Component.

Functional Component: Là một function return JSX. Không có state, hook. Loại component này chỉ được sử dụng để đổ data và hiển thị lên view.

Ưu điểm của loại component này là cực kỳ nhanh do có kích thước nhỏ nhất trong 3 loại Component trên.

Class Component: Là một class với đầy đủ các tính năng, có hàm render return về JSX, constructor để khởi tạo state, sử dụng hook, function, v.v.

Pure Component: Mang trong mình đầy đủ tính năng của Class Component. Tuy nhiên, Component này khác Class Component ở chỗ được custom lại hook shouldComponentUpdate. Class Component sẽ được render mỗi khi app chạy, khi chúng ta navigate qua lại giữa các component thì hàm render trong Class Component luôn luôn được gọi.

Không giống như Class Component, PureComponent chỉ render lại khi có props hoặc state thay đổi.

Summary: Nên sử dụng Functional / Stateless Component để hiển thị dữ liệu và show lên view. Hạn chế sử dụng Class Component và thay bằng PureComponent.

Passing props Component

Không nên truyền những props quá chung chung, hoặc truyền 1 mớ vào một Component như sau:

const Person = props => <div {...props}>{props.text}</div>

Nên định nghĩa chính xác những property nào mà ta muốn truyền vào, như sau:

const Person = props => (
  <div specificAttribute={props.specificAttribute}>{props.text}</div>
)

Dependency optimization

Việc dùng thư viện của bên thứ 3 là điều gần như là bắt buộc trong phát triển ứng dụng bằng React (vì bản chất React không phải là 1 framework hoàn thiện, React chỉ là 1 thư viện để xây dựng UI mà thôi).

Dùng thư viện bên thứ 3 thì không có gì sai nhưng phải dùng sao cho đúng cách.

Chỉ import những gì mà mình sử dụng, không nên import thừa thãi, làm giảm tốc độ load của app

Ví dụ về một thư viện khá phố biến và hầu như ai cũng đã từng sử dụng, đó là lodash

Bad

import _ from 'lodash'

const person = {}
_.isEmpty(person) // true

Good

import _isEmpty from 'lodash/isEmpty'

const person = {}
_isEmpty(person) // true

Sử dụng React.Fragment để tránh wrapper nhiều lớp div

React chỉ cho phép return về 1 nodo. Do đó, chúng ta thường có thói quen wrap 1 class div bên ngoài. Điều này cũng không sai nhưng không phải tốt nhất, thậm chí còn làm cây DOM của chúng ta trông rất rối

=> Hãy chuyển sang sử dụng React.Fragment

Bad

const Person = () => (
  <div>
    <p>name</p>
    <p>age</p>
    <p>job</p>
  </div>
)

Good

const Person = () => (
  <React.Fragment>
    <p>name</p>
    <p>age</p>
    <p>job</p>
  </React.Fragment>
)

Ở những bản React gần đây thì chúng ta có thể sử dụng cú pháp <></> để thay thế cho <React.Fragment></React.Fragment>

Extremely Good

const Person = () => (
  <>
    <p>name</p>
    <p>age</p>
    <p>job</p>
  </>
)

Hạn chế những phép tính toán phức tạp trong hàm render() hoặc JSX

Nếu như có trên 3 phép tính toán để hiển thị được kết quả cuối cùng thì chúng ta nên tách ra thành một hàm riêng, tính toán sau đó trả về dữ liệu.

Bad

render() {
    const { num1, num2 } = this.props;
    const sum = num1 + num2;
    const max = Max(num1, num2);

    return (
        <div>
            Sum: {sum}
            Max: {Max(num1, num2)}
        </div>
    )
}

Good

getSum = () => {
    const { num1, num2 } = this.props;
    return num1 + num2;
}

getMax = () => {
    const { num1, num2 } = this.props;
    return Max(num1, num2);
}

render() {
    return (
        <div>
            Sum: {this.getSum()}
            Max: {this.getMax()}
        </div>
    )
}

Tránh sử dụng index để làm key trong hàm map()

Không nên sử dụng index làm key khi render nhiều Component trong function map(). Index dùng để xác định các thành phần DOM.

Giả sử, có 10 Component được render thông qua functiona map(), mỗi Component này được gắn key=index. Khi này việc push hoặc remove bất kì Component nào trong list Component trên sẽ làm sai số các Component.

Key phải là unique, do đó nên sử dụng những thuật toán hoặc các thư viện để generate các đoạn string dùng làm key. Hoặc nếu dữ liệu có trường unique (eg id) thì nên sử dụng để làm key cho các Component.

Bad

persons.map((person, index) => <Person key={index} data={person} />)

Good

import shortid from 'shortid'

persons.map(person => <Person key={shortid} data={person} />)

Extremly Good

persons.map(person => <Person key={person.id} data={person} />)

Hey. I'm Thuan.
I write anything to help others.