Tổng quan về trình thực thi

Cách trình chạy web và trình chạy dịch vụ có thể cải thiện hiệu suất của trang web, cũng như thời điểm sử dụng trình chạy web so với trình chạy dịch vụ.

Andrew Guan
Andrew Guan
Demián Renzulli
Demián Renzulli

Thông tin tổng quan này giải thích cách worker web và worker dịch vụ có thể cải thiện hiệu suất của trang web, cũng như thời điểm sử dụng worker web so với worker dịch vụ. Hãy xem phần còn lại của loạt bài này để biết các mẫu cụ thể về giao tiếp giữa cửa sổ và worker dịch vụ.

Cách worker có thể cải thiện trang web của bạn

Trình duyệt sử dụng một luồng duy nhất (luồng chính) để chạy tất cả JavaScript trong một trang web, cũng như để thực hiện các tác vụ như hiển thị trang và thu gom rác. Việc chạy quá nhiều mã JavaScript có thể chặn luồng chính, khiến trình duyệt trì hoãn việc thực hiện các tác vụ này và dẫn đến trải nghiệm người dùng kém.

Trong quá trình phát triển ứng dụng iOS/Android, một mẫu phổ biến để đảm bảo luồng chính của ứng dụng vẫn có thể phản hồi các sự kiện của người dùng là chuyển các thao tác sang các luồng bổ sung. Trên thực tế, trong các phiên bản Android mới nhất, việc chặn luồng chính quá lâu sẽ dẫn đến sự cố ứng dụng.

Trên web, JavaScript được thiết kế dựa trên khái niệm về một luồng và thiếu các chức năng cần thiết để triển khai mô hình nhiều luồng như mô hình mà các ứng dụng có, chẳng hạn như bộ nhớ dùng chung.

Mặc dù có những hạn chế này, nhưng bạn vẫn có thể đạt được một mẫu tương tự trên web bằng cách sử dụng worker để chạy tập lệnh trong luồng nền, cho phép các worker thực hiện tác vụ mà không can thiệp vào luồng chính. Worker là toàn bộ phạm vi JavaScript chạy trên một luồng riêng biệt, không có bộ nhớ dùng chung.

Trong bài đăng này, bạn sẽ tìm hiểu về hai loại worker (worker web và worker dịch vụ), điểm giống và khác nhau giữa các worker này cũng như các mẫu phổ biến nhất để sử dụng worker trong trang web chính thức.

Sơ đồ cho thấy hai đường liên kết giữa đối tượng Window và worker web và worker dịch vụ.

Trình chạy web và trình chạy dịch vụ

Điểm tương đồng

Trình chạy webtrình chạy dịch vụ là hai loại trình chạy có sẵn cho trang web. Các loại này có một số điểm chung:

  • Cả hai đều chạy trong luồng phụ, cho phép mã JavaScript thực thi mà không chặn luồng chính và giao diện người dùng.
  • Các đối tượng này không có quyền truy cập vào đối tượng WindowDocument, vì vậy, chúng không thể tương tác trực tiếp với DOM và có quyền truy cập hạn chế vào API trình duyệt.

Sự khác biệt

Bạn có thể nghĩ rằng hầu hết những việc có thể được uỷ quyền cho một worker web đều có thể được thực hiện trong một worker dịch vụ và ngược lại, nhưng có những điểm khác biệt quan trọng giữa chúng:

  • Không giống như worker web, worker dịch vụ cho phép bạn chặn các yêu cầu mạng (thông qua sự kiện fetch) và nghe các sự kiện API đẩy ở chế độ nền (thông qua sự kiện push).
  • Một trang có thể tạo nhiều trình chạy web, nhưng một trình chạy dịch vụ duy nhất sẽ kiểm soát tất cả các thẻ đang hoạt động trong phạm vi mà trình chạy dịch vụ đó được đăng ký.
  • Vòng đời của worker web được ghép nối chặt chẽ với thẻ mà worker đó thuộc về, trong khi vòng đời của worker dịch vụ lại độc lập với vòng đời của worker web. Vì lý do đó, việc đóng thẻ mà trình chạy web đang chạy sẽ chấm dứt trình chạy đó, trong khi trình chạy dịch vụ có thể tiếp tục chạy ở chế độ nền, ngay cả khi trang web không có thẻ nào đang mở.

Trường hợp sử dụng

Sự khác biệt giữa cả hai loại worker cho biết trong trường hợp nào bạn nên sử dụng loại worker này hoặc loại worker kia:

Các trường hợp sử dụng worker web thường liên quan đến việc giảm tải công việc (chẳng hạn như các phép tính tốn kém) sang luồng phụ để tránh chặn giao diện người dùng.

Sơ đồ thể hiện đường liên kết từ đối tượng Window đến một worker web.
  • Ví dụ: nhóm đã tạo trò chơi điện tử PROXX muốn để luồng chính được tự do nhất có thể để xử lý hoạt ảnh và dữ liệu đầu vào của người dùng. Để đạt được điều đó, họ đã sử dụng trình chạy web để chạy logic trò chơi và duy trì trạng thái trên một luồng riêng biệt.
Ảnh chụp màn hình trò chơi điện tử PROXX.

Các tác vụ của trình chạy dịch vụ thường liên quan nhiều hơn đến việc đóng vai trò là proxy mạng, xử lý các tác vụ trong nền và những việc như lưu vào bộ nhớ đệm và ngoại tuyến.

Ảnh chụp màn hình trò chơi điện tử PROXX.

Ví dụ: Trong một PWA podcast, bạn có thể muốn cho phép người dùng tải các tập đầy đủ xuống để nghe khi không có mạng. Bạn có thể sử dụng trình chạy dịch vụ và cụ thể là Background Fetch API (API Tìm nạp trong nền) cho mục đích đó. Nhờ đó, nếu người dùng đóng thẻ trong khi tập đang tải xuống, thì tác vụ sẽ không bị gián đoạn.

Ảnh chụp màn hình của một PWA Podcast.
Giao diện người dùng được cập nhật để cho biết tiến trình tải xuống (bên trái). Nhờ các worker dịch vụ, thao tác này có thể tiếp tục chạy khi tất cả các thẻ đã đóng (bên phải).

Công cụ và thư viện

Bạn có thể triển khai giao tiếp giữa cửa sổ và worker bằng cách sử dụng nhiều API cấp thấp hơn. May mắn thay, có các thư viện tóm tắt quy trình này, xử lý các trường hợp sử dụng phổ biến nhất. Trong phần này, chúng ta sẽ đề cập đến hai trong số đó, tương ứng là ComlinkWorkbox. Các công cụ này sẽ xử lý cửa sổ cho worker web và worker dịch vụ.

Ảnh chụp màn hình trò chơi điện tử PROXX.

Comlink là một thư viện RPC nhỏ (1,6k) giúp xử lý nhiều thông tin chi tiết cơ bản khi xây dựng các trang web sử dụng Web Worker. Công cụ này đã được sử dụng trong các trang web như PROXXSquoosh. Bạn có thể xem bản tóm tắt về lý do và mã mẫu của thư viện này tại đây.

Workbox

Workbox là một thư viện phổ biến để xây dựng các trang web sử dụng worker dịch vụ. Thư viện này đóng gói một bộ các phương pháp hay nhất liên quan đến các hoạt động như lưu vào bộ nhớ đệm, ngoại tuyến, đồng bộ hoá trong nền, v.v. Mô-đun workbox-window cung cấp một cách thuận tiện để trao đổi thông báo giữa worker dịch vụ và trang.

Các bước tiếp theo

Phần còn lại của loạt bài này tập trung vào các mẫu giao tiếp giữa cửa sổ và worker dịch vụ:

Để biết các mẫu giao tiếp giữa cửa sổ và worker web, hãy xem bài viết: Sử dụng worker web để chạy JavaScript ngoài luồng chính của trình duyệt.