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

Cho đến nay, hầu hết nội dung trong khoá học này đều tập trung vào các khái niệm như các cân nhắc chung về hiệu suất HTML, gợi ý về tài nguyên, tối ưu hoá các các 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 cho người dùng đầu vào 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 hiệu suất liên quan đến JavaScript vẫn chưa được chưa được đề cập đến 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 mà học phần này và học phần tiếp theo đề cập đến.

JavaScript thường được mô tả là ngôn ngữ đơn luồng. Trong thực tế, đây là đề cập đến luồng chính (luồng chính duy nhất mà trình duyệt thực hiện) hầu hết công việc bạn thấy trong trình duyệt. Công việc này bao gồm các nhiệm vụ liên quan về những việc như viết tập lệnh, một số loại công việc kết xuất, 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 nâng cao trải nghiệm người dùng. Trên thực tế, các trình duyệt sử dụng các luồng khác để thực hiện những việc mà bạn (với tư cách là nhà phát triển) không thường có quyền truy cập trực tiếp vào, chẳng hạn như các luồng GPU.

Khi có quan ngại về JavaScript, bạn thường chỉ tập trung vào 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.

Nhân viên web rất hữu ích khi bạn có công việc tính toán tốn kém chỉ không thể chạy trên luồng chính mà không gây ra các tác vụ mất nhiều thời gian khiến trang không phản hồi. Các tác vụ như vậy chắc chắn có thể ảnh hưởng đến Tương tác với Next Paint (INP), nhờ đó, bạn sẽ biết được khi nào mình có công việc có thể thực hiện hoàn toàn khỏi 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 để người dùng tương tác 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 nội dung trên web nhân viên. Bản minh hoạ cho thấy cách bạn có thể sử dụng web worker để thực hiện công việc đọc siêu dữ liệu hình ảnh từ tệp JPEG ngoài chuỗi chính — và cách bạn có thể đưa siêu dữ liệu đó trở lại luồng chính để người dùng xem.

Cách khởi chạy nhân viên web

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

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

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

Giới hạn của trình chạy web

Không giống như JavaScript chạy trên luồng chính, nhân viên 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. Web worker phải tuân theo những hạn chế 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 tin nhắn quy trình, tức là nhân viên web có thể gián tiếp truy cập vào DOM theo cách.
  • Phạm vi của trình chạy web là self, thay vì window.
  • Phạm vi trình chạy web quyền truy cập vào các dữ liệu gốc của JavaScript và cấu trúc, 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 giao tiếp với window

Nhân viên web có thể giao tiếp với window của luồng chính ngữ cảnh thông qua quy trình nhắn tin. Đường ống này cho phép bạn chuyển dữ liệu đến và từ luồng chính và worker 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 một sự kiện message trên ngữ cảnh của trình thực thi 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 trong ngữ cảnh window trên luồng chính, bạn có thể nhận được thông báo từ chuỗi trình chạy 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 nhắn tin của nhân viên web là một lối thoát khác từ web ngữ cảnh của worker. Bằng cách sử dụng nó, bạn có thể gửi dữ liệu đến 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 luồng chính.

Kiểm tra kiến thức của bạn

Một nhân viên web chạy trên luồng nào?

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

Nhân viên web có thể truy cập vào nội dung nào?

Dữ liệu gốc của JavaScript, chẳng hạn như mảng và đối tượng.
Chính xác!
Một tập hợp con nghiêm ngặt các API có sẵn trong ngữ cảnh window, bao gồm 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 để nhân viên web truy cập vào ngữ cảnh "window"?

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.
Nhân viên web không thể truy cập vào window bằng bất kỳ phương tiện nào.
Hãy thử lại.
Thông qua một quy trình nhắn tin được hỗ trợ bởi postMessage trong ngữ cảnh trình chạy web (self).
Chính xác!

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

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