0
0
Lập trình
Admin Team
Admin Teamtechmely

🚀 Tối ưu hóa Hiệu suất Frontend: Giải pháp cho Long Task trong JavaScript

Đăng vào 3 tuần trước

• 3 phút đọc

Tối ưu Hiệu suất Frontend với Long Task trong JavaScript

Như các bạn đã biết, JavaScript là một ngôn ngữ lập trình đơn luồng (single-threaded), có nghĩa là nó chỉ có thể thực hiện một tác vụ tại một thời điểm. Khi một tác vụ mất quá nhiều thời gian (Long Task) để hoàn thành, nó có thể khiến trình duyệt trở nên không phản hồi hoặc chậm chạp.

Để tối ưu hóa một tác vụ dài (Long Task), điều quan trọng trước tiên là bạn cần nắm rõ về Event Loop, cơ chế chính trong JavaScript Runtime giúp quản lý và xử lý các event, task và các thao tác bất đồng bộ.

Hiểu rõ về Event Loop

Các bước thực hiện trong Event Loop:

  1. Event Loop liên tục kiểm tra hai queue: Task Queue và Microtask Queue. Khi Call Stack trống, nó sẽ chuyển sang bước 2.
  2. Nếu Microtask Queue có chứa task, Event Loop sẽ thực thi tất cả các task đó trên Call Stack trước khi chuyển qua Task Queue.
  3. Nếu Task Queue có task, Event Loop sẽ thực thi task đầu tiên trong Task Queue.
  4. Nếu tác vụ trong bước 3 hoàn thành và tạo ra các task mới trên Microtask Queue, Event Loop sẽ quay lại thực hiện bước 2. Khi Microtask Queue trống, nó sẽ chuyển về bước 3.

Một số lưu ý:

  • Microtask Queue bao gồm: Callbacks từ Promises (then, catch, finally), Callbacks từ MutationObserver, và queueMicrotask,...
  • Task Queue bao gồm: setTimeout, setInterval, các callback events (onscroll, onclick,...).
  • Thứ tự thực hiện của Event Loop là: Thao tác đồng bộ > Microtasks > Macrotasks.
  • Nếu gặp await, mọi thứ sau await sẽ được đưa vào Microtask Queue.
  • Macrotasks chỉ được thực thi khi Call Stack và Microtask Queue đều trống.
  • Lưu ý rằng nếu bạn liên tục đưa task vào Microtask Queue, trình duyệt sẽ bị lag.

Hãy cùng nhau khám phá cách tối ưu hóa Long Task với một vài ví dụ cụ thể nhé.

Tối ưu Long Task

Ví dụ 1: Chia nhỏ tác vụ

Dưới đây là một Long Task có thể khiến trình duyệt bị lag, làm người dùng không thể tương tác. Khi bạn chạy tab Performance, bạn sẽ thấy Long Task chiếm hoàn toàn main thread và dẫn đến hiện tượng lag.

Để tối ưu hóa Long Task này, bạn có thể kết hợp setTimeout để chia nhỏ Long Task thành 10 Task nhỏ hơn. Những Task nhỏ này sẽ được đưa vào MacroTask Queue để thực thi.

Chạy lại Performance, bạn sẽ nhận thấy có nhiều Task nhỏ hơn đang chạy. Kiểm tra kỹ hơn, bạn sẽ thấy giữa các Task nhỏ có thêm các Task khác, chẳng hạn như xử lý tương tác người dùng hoặc render UI, nên trình duyệt vẫn diễn ra mượt mà.

Ví dụ 2: Tối ưu hóa hàm saveSettings

Chúng ta sẽ xem một ví dụ thực tế hơn về hàm saveSettings, trong đó bao gồm 5 hàm con đảm nhiệm việc hiển thị giao diện, lưu dữ liệu vào cơ sở dữ liệu và phân tích dữ liệu.

Nếu gọi cả 5 hàm một cách đồng bộ, nó có thể tạo ra một Long Task, gây chậm cho trình duyệt. Chạy Performance để xem kết quả bạn sẽ thấy.

Để cải thiện hiệu suất, chúng ta nên thực hiện các công việc quan trọng trước và trì hoãn các công việc không quan trọng bằng cách sử dụng setTimeout hoặc yield.

Chạy lại Performance và bạn sẽ thấy kết quả tối ưu hóa với cả hai phương pháp. Kiểm tra kỹ hơn, bạn sẽ thấy giữa các Task nhỏ cũng có các Task khác để xử lý tương tác người dùng hoặc render, giúp trình duyệt vẫn hoạt động mượt mà.

Kết luận

Hi vọng qua hai ví dụ trên, bạn đã nắm được kỹ thuật tối ưu Long Task để áp dụng ngay cho dự án của mình. Đừng quên kết nối với mình qua Youtube và LinkedIn để khám phá thêm nhiều bài viết thú vị khác nhé:

Tài liệu tham khảo

  1. Event Loop trong JavaScript
  2. Video về Event Loop
  3. Hướng dẫn tối ưu Long Task
    source: viblo
Gợi ý câu hỏi phỏng vấn
Không có dữ liệu

Không có dữ liệu

Bài viết được đề xuất
Bài viết cùng tác giả

Bình luận

Chưa có bình luận nào

Chưa có bình luận nào