Automatic Batching – Cải tiến đáng giá trên React 18

Vừa qua ngày 8/3, team React đã giới thiệu React 18 RC (Release Candidate) với 1 số các tính năng mới cập nhật đáng giá. Trong số đó, đáng chú ý là feature mới: Automatic Batching giúp tối ưu hóa cho việc render. Bài viết hôm nay chúng ta cùng đi tìm hiểu về nó để thấy được team phát triển React đã và đang thực sự quan tâm đến việc cải thiện performance của thư viện này thế nào.

Batching là gì?

Như chúng ta đã biết, mặc định mỗi lần gọi setState() thì React sẽ bắt đầu 1 quá trình render mới, một cách đồng bộ và trả về. Khi chúng ta gọi setState 2 lần liên tiếp nhau thì app của chúng ta cũng sẽ render 2 lần. Để tối ưu việc render này thì React cung cấp 1 khái niệm gọi là “render batching”; để thay vì gọi setState nhiều lần thì React sẽ tự batch các lần gọi liên tiếp nhau vào để chỉ phải chạy re-render 1 lần duy nhất.

https://reactjs.org/docs/state-and-lifecycle.html#state-updates-may-be-asynchronous

Trên docs của React có đề cập tới đoạn: state updates may be asyncronous – nguyên nhân là do việc React tự động batch các state updates xảy ra trong các React event handlers (xử lý các sự kiện trong React).

Lưu ý ở đây là với các phiên bản React trước (từ 17 trở xuống) thì việc batching chỉ được thực hiện trong các React event handlers. Điều đấy cũng có nghĩa là những updates xảy ra trong các promises, setTimeout, native event handlers hoặc các event khác sẽ không được batched.

Và đây cũng chính là update mới trong React 18:

Automatic Batching

https://reactjs.org/blog/2022/03/29/react-v18.html

Chúng ta cùng xem đoạn code dưới đây:

Và đây là cách React 18 xử lý so với React 17.

Thực sự thì đây là 1 cải tiến đáng giá của team React trong việc tối ưu performance. Việc các ứng dụng React của chúng ta ngày càng phình to, xử lý rất nhiều các actions bất đồng bộ thì đoạn re-render khiến app bị ảnh hưởng rất lớn đến performance. Nếu xử lý skip được 1 cơ số lần render thừa như vậy thì app của chúng ta sẽ mượt mà hơn rất nhiều.

Sâu hơn chút

Chúng ta cùng đi sâu hơn 1 chút, React đã làm thế nào để xử lý render batching?

Có 1 internal function được sinh ra để wrap các lần setState lại có tên là unstable_batchedUpdates. React theo dõi tất các các state updates được gọi khi unstable_batchedUpdates đang chạy và sau đó áp dụng chúng trong 1 lần render duy nhất.

Bạn có thể hình dung những gì React đang hoạt động như đoạn code dưới đây:

function internalHandleEvent(e) {
  const userProvidedEventHandler = findEventHandler(e);
  
  let batchedUpdates = [];
  
  unstable_batchedUpdates(() => {
    // mọi state updates được gọi tại đây sẽ được push vào batchedUpdates
    userProvidedEventHandler(e);
  });
  
  renderWithQueuedStateUpdates(batchedUpdates);
}

Thực hành

OK, đến đây thì các bạn đã hiểu hơn về render batching cũng như feature mới Automatic Batching trên React 18 rồi đúng không. Hãy thử 1 ví dụ cuối bài lần nữa nhé.

Với bạn code dưới đây, theo bạn thì component sẽ được thực render bao nhiêu lần đối với React-17 và React-18?

const [counter, setCounter] = useState(0);

const onClick = async () => {
  setCounter(0);
  setCounter(1);
  
  const data = await fetchSomeData();
  
  setCounter(2);
  setCounter(3);
}

Cảm ơn các bạn đã đọc bài! Hy vọng bài viết hữu ích cho mọi người.

Bình luận

Để lại một bình luận

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *