Tổng quan về nhân viên web

Cho đến nay, nhiều nội dung trong khoá học này tập trung vào các khái niệm như cân nhắc chung về hiệu suất HTML, gợi ý tài nguyên, tối ưu hoá nhiều loại tài nguyên để cải thiện thời gian tải trang ban đầu và khả năng phản hồi hoạt động đầu vào của người dùng, cũng như tải từng phần các tài nguyên cụ thể.

Tuy nhiên, có một khía cạnh về hiệu suất liên quan đến JavaScript chưa được đề cập trong khoá học này, đó là vai trò của nhân viên web trong việc cải thiện khả năng phản hồi đầu vào. Bài học này cũng như học phần tiếp theo sẽ đề cập đến.

JavaScript thường được mô tả là một ngôn ngữ đơn luồng. Trên thực tế, đây là luồng chính, là luồng đơn mà trình duyệt thực hiện hầu hết tác vụ mà bạn thấy trong trình duyệt. Công việc này bao gồm các tác vụ liên quan đến các nội dung như viết tập lệnh, một số loại công việc kết xuất hình ảnh, phân tích cú pháp HTML và CSS và các loại công việc khác dành cho người dùng nhằm cải thiện trải nghiệm người dùng. Trên thực tế, trình duyệt sử dụng các luồng khác để thực hiện công việc mà bạn, nhà phát triển, thường không có quyền truy cập trực tiếp, chẳng hạn như các luồng GPU.

Khi lo ngại về JavaScript, bạn thường bị giới hạn trong việc thực hiện tác vụ trên luồng chính, nhưng chỉ theo mặc định. Bạn có thể đăng ký và sử dụng các luồng bổ sung trong JavaScript. Tính năng cho phép đa luồng trong JavaScript được gọi là API Web Workers.

Trình thực thi web rất hữu ích khi bạn có một khối lượng công việc tính toán tiêu tốn tài nguyên tính toán mà không thể chạy trên luồng chính mà không gây ra các tác vụ dài khiến trang không phản hồi. Những nhiệm vụ như vậy chắc chắn có thể ảnh hưởng đến Lượt tương tác với Nội dung hiển thị tiếp theo (INP) trên trang web của bạn. Vì vậy, bạn nên biết khi nào bạn có công việc có thể được thực hiện hoàn toàn trên luồng chính. Việc này có thể giúp tạo thêm không gian cho các tác vụ khác trên luồng chính để tương tác của người dùng nhanh hơn.

Mô-đun này và bản minh hoạ tiếp theo cho thấy một trường hợp sử dụng cụ thể bao gồm cả trình thực thi web. Bản minh hoạ này cho thấy cách bạn có thể sử dụng trình chạy web để thực hiện công việc đọc siêu dữ liệu hình ảnh từ tệp JPEG ngoài luồng chính, và cách bạn có thể đưa siêu dữ liệu đó quay lại luồng chính để người dùng xem.

Cách khởi chạy một trình chạy web

Một trình chạy web được đăng ký bằng cách tạo thực thể của lớp Worker. Khi thực hiện việc này, bạn sẽ chỉ định vị trí của mã worker web, nơi trình duyệt tải và sau đó tạo một luồng mới. Luồng thu được thường được gọi là luồng worker.

const myWebWorker = new Worker('/js/my-web-worker.js');

Trong tệp JavaScript của trình chạy (my-web-worker.js trong trường hợp này), bạn có thể viết mã để chạy trong một luồng thực thi riêng biệt.

Giới hạn của nhân viên web

Không giống như JavaScript chạy trên luồng chính, trình chạy web không có quyền truy cập trực tiếp vào ngữ cảnh window và có quyền truy cập hạn chế vào các API mà nó cung cấp. Trình chạy web phải tuân theo các quy tắc ràng buộc sau:

  • Nhân viên web không thể truy cập trực tiếp vào DOM.
  • Nhân viên web có thể giao tiếp với ngữ cảnh window thông qua quy trình nhắn tin, nghĩa là nhân viên web có thể gián tiếp truy cập vào DOM theo một cách nào đó.
  • Phạm vi của trình chạy web là self, thay vì window.
  • Phạm vi của trình chạy web quyền truy cập vào các cấu trúc và dữ liệu gốc JavaScript, cũng như các API như fetchmột số lượng khá lớn các API khác.

Cách nhân viên web trao đổi với window

Một worker có thể giao tiếp với ngữ cảnh window của luồng chính thông qua một quy trình thông báo. Quy trình này cho phép bạn chuyển dữ liệu đến và đi từ luồng chính cũng như trình thực thi web. Để gửi dữ liệu từ một trình chạy web đến luồng chính, bạn cần thiết lập sự kiện message trên ngữ cảnh của trình chạy web (self)

// my-web-worker.js
self.addEventListener("message", () => {
  // Sends a message of "Hellow, window!" from the web worker:
  self.postMessage("Hello, window!");
});

Sau đó, trong một tập lệnh theo ngữ cảnh window trên luồng chính, bạn có thể nhận được thông báo từ luồng worker web bằng cách sử dụng một sự kiện message khác:

// scripts.js

// Creates the web worker:
const myWebWorker = new Worker('/js/my-web-worker.js');

// Adds an event listener on the web worker instance that listens for messages:
myWebWorker.addEventListener("message", ({ data }) => {
  // Echoes "Hello, window!" to the console from the worker.
  console.log(data);
});

Quy trình thông báo của trình thực thi web là một giải pháp thoát hiểm từ ngữ cảnh của trình thực thi web. Bằng cách sử dụng công cụ này, bạn có thể gửi dữ liệu tới window từ trình thực thi web mà bạn có thể sử dụng để cập nhật DOM hoặc thực hiện công việc khác phải được thực hiện trên luồng chính.

Kiểm tra kiến thức

Trình chạy web chạy trên luồng nào?

Luồng chính.
Hãy thử lại.
Luồng riêng của luồng đó (còn được gọi là luồng worker trên web).
Chính xác!
Luồng GPU.
Hãy thử lại.

Web worker có thể truy cập những gì?

Dữ liệu gốc JavaScript, chẳng hạn như mảng và đối tượng.
Chính xác!
Một tập hợp con API nghiêm ngặt có sẵn trong ngữ cảnh window, bao gồm cả fetch.
Chính xác!
Ngữ cảnh window, nhưng chỉ gián tiếp.
Chính xác!

Làm cách nào để một trình chạy web có thể truy cập vào ngữ cảnh "cửa sổ"?

Trực tiếp, bằng cách tham chiếu các thành phần của đối tượng window.
Hãy thử lại.
Trình thực thi web không thể truy cập vào window bằng bất kỳ cách nào.
Hãy thử lại.
Thông qua một quy trình thông báo được phương thức postMessage hỗ trợ trong ngữ cảnh trình chạy web (self).
Chính xác!

Tiếp theo: trường hợp sử dụng worker cụ thể trên web

Trong mô-đun tiếp theo, trường hợp sử dụng worker cụ thể trên web sẽ được trình bày chi tiết và minh hoạ. Trong mô-đun đó, một trình chạy web được dùng để tìm nạp tệp JPEG từ một URL nhất định và đọc siêu dữ liệu Exif của tệp đó trong một trình chạy web. Sau đó, dữ liệu đó được gửi lại luồng chính để hiển thị cho người dùng.