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 có 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 có 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ư
fetch
và mộ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?
Web worker có thể truy cập những gì?
window
, bao gồm cả fetch
.
window
, nhưng chỉ gián tiếp.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ổ"?
window
.
window
bằng bất kỳ cách nào.
postMessage
hỗ trợ trong ngữ cảnh trình chạy web (self
).
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.