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 có 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 có 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ư
fetch
và mộ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?
Nhân viên web có thể truy cập vào nội dung nào?
window
, nhưng chỉ gián tiếp.window
,
bao gồm fetch
.
Làm cách nào để nhân viên web truy cập vào ngữ cảnh "window"?
window
bằng bất kỳ phương tiện nào.
window
.
postMessage
trong ngữ cảnh trình chạy web (self
).
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.